notcurses_metric(3)

πŸ’– NAME πŸ’–

okay bestie, welcome to notcurses_metric(3) β€” the notcurses manual page for fixed-width numeric output with metric suffixes ✨ this is the one that makes big numbers look cute and aligned, no cap.


πŸŽ€ SYNOPSIS πŸŽ€

copy these exact characters, bestie β€” no autocorrect, no β€œfixing” anything πŸ’…

       #include <notcurses/notcurses.h>

              #define NCPREFIXCOLUMNS 7
              #define NCIPREFIXCOLUMNS 8
              #define NCBPREFIXCOLUMNS 9
              #define NCPREFIXSTRLEN (NCPREFIXCOLUMNS + 1)
              #define NCIPREFIXSTRLEN (NCIPREFIXCOLUMNS + 1)
              #define NCBPREFIXSTRLEN (NCBPREFIXCOLUMNS + 1)
              #define NCMETRICFWIDTH(x, cols) ((int)(strlen(x) - ncstrwidth(x) + (cols)))
              #define NCPREFIXFMT(x) NCMETRICFWIDTH((x), NCPREFIXCOLUMNS), (x)
              #define NCIPREFIXFMT(x) NCMETRIXFWIDTH((x), NCIPREFIXCOLUMNS), (x)
              #define NCBPREFIXFMT(x) NCMETRICFWIDTH((x), NCBPREFIXCOLUMNS), (x)

       const char* ncnmetric(uintmax_t val, size_t s, uintmax_t decimal, char*
       buf, int omitdec, unsigned mult, int uprefix);

       static inline const char* ncqprefix(uintmax_t val, uintmax_t decimal,
       char* buf, int omitdec);

       static inline const char* nciprefix(uintmax_t val, uintmax_t decimal,
       char* buf, int omitdec);

       static inline const char* ncbprefix(uintmax_t val, uintmax_t decimal,
       char* buf, int omitdec);

🌸 DESCRIPTION 🌸

ncnmetric (plus the helper wrappers nc[qib]prefix) accepts very large β€” or very small β€” non-negative integers, and prepares formatted output of a maximum width using metric suffixes. the suffix can represent arbitrary amounts of growth, but it’s designed for 1000 (NCPREFIX) or 1024 (NCIPREFIX). that 1024 situation is for β€œdigital units of information”, i.e. kibibytes and gibibits. ncnmetric supports the large suffixes KMGTPEZY (Kilo, Mega, Giga, Tera, Peta, Exa, Zetta, and Yotta) and the small suffixes mΒ΅npfazy (Milli, Micro, Nano, Pico, Femto, Atto, Zepto, and Yocto). this covers the range 1e24 (one septillion) through 1e-24, sufficing for all possible values of a 64-bit uintmax_t. iconic range honestly πŸ’–

val is the value being output, having been scaled by decimal. decimal will typically be 1; to represent values less than 1, decimal should be larger than val. the output will be written to buf, which must be at least:

  • NCPREFIXSTRLEN + 1 bytes for a 1000-based value
  • NCIPREFIXSTRLEN + 1 bytes for a 1024-based value
  • NCBPREFIXSTRLEN + 1 bytes for a 1024-based value with an 'i' suffix

<s>no cap</s> no cap, check your buffer sizes bestie 🫢

s is the maximum output size, including '\0', used in the same fashion as snprintf(3) (which ncnmetric calls).

three helper functions are provided to simplify these common cases β€” exact code, no edits:

              // Mega, kilo, gigafoo. Use NCPREFIXSTRLEN + 1 and NCPREFIXCOLUMNS.
              static inline const char*
              ncqprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
                return ncnmetric(val, decimal, buf, omitdec, 1000, '\0');
              }

              // Mibi, kebi, gibibytes sans 'i' suffix. Use NCIPREFIXSTRLEN + 1.
              static inline const char*
              nciprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
                return ncnmetric(val, decimal, buf, omitdec, 1024, '\0');
              }

              // Mibi, kebi, gibibytes. Use NCBPREFIXSTRLEN + 1 and NCBPREFIXCOLUMNS.
              static inline const char*
              ncbprefix(uintmax_t val, uintmax_t decimal, char* buf, int omitdec){
                return ncnmetric(val, decimal, buf, omitdec, 1024, 'i');
              }

if omitdec is not zero, the decimal point and mantissa will be omitted if all digits to be displayed would be zero. the decimal point takes the current locale into account (see setlocale(3) and localeconv(3)). mult is the relative multiple for each suffix. uprefix, if not zero, will be used as a suffix following any metric suffix.

the maximum number of columns is not directly related to the maximum number of bytes, since Unicode doesn’t necessarily map to single-byte characters (including the 'Β΅' micro suffix). the corresponding defines for maximum column length are:

  • NCPREFIXCOLUMNS (7)
  • NCIPREFIXCOLUMNS (8)
  • NCBPREFIXCOLUMNS (9)

in general, the maximum-width output will take the form CCC.mmMu, where C are digits of the characteristic (up to ceil(log10(mult)) digits), the decimal point follows, m are digits of the mantissa (up to 2), M is the metric suffix, and u is the uprefix. the minimum-width output will take the form C. this minimal form can occur if omitdec is non-zero and a single-column value such as 5 is passed for val.

three more defines are provided to simplify formatted fixed-width output using the results of ncnmetric. each of these macros accepts a character buffer holding the result of the call, and expand to two arguments:

  • NCPREFIXFMT(x)
  • NCIPREFIXFMT(x)
  • NCBPREFIXFMT(x)

these can be used in e.g. the following ungainly fashion:

**ncplane_printf(n, "%*s", NCPREFIXFMT(buf));**

to ensure that the output is always NCPREFIXCOLUMNS wide. slay alignment πŸ’…βœ¨


πŸ¦‹ RETURN VALUES πŸ¦‹

NULL if input parameters were invalid, or if notcurses_init has not been successfully called. otherwise, a pointer to buf, filled in with the formatted output.


πŸ“ EXAMPLES πŸ“

here’s the whole little demo reel, exact:

ncnmetric(0, INT_MAX, buf, 0, 1000, '\0'): "0.00".

ncnmetric(0, INT_MAX, buf, 1, 1000, '\0'): "0".

ncnmetric(1023, INT_MAX, buf, 1, 1000, '\0'): "1.02K".

ncnmetric(1023, INT_MAX, buf, 1, 1024, 'i'): "1023".

ncnmetric(1024, INT_MAX, buf, 1, 1024, 'i'): "1Ki".

ncnmetric(4096, INT_MAX, buf, 0, 1024, 'i'): "4.00Ki".

ncnmetric(0x7fffffffffffffff, INT_MAX, buf, 0, 1000, '\0'): "9.22E".

ncnmetric(0xffffffffffffffff, INT_MAX, buf, 0, 1000, '\0'): "18.45E".

πŸ’€ BUGS πŸ’€

real talk: this function is difficult to understand, and takes too many arguments. 😭

if UTF-8 is available, 'Β΅' (U+00B5 MICRO SIGN) will be used in place of 'u' (U+0075 LATIN SMALL LETTER U) for the 'micro-' prefix. this is determined by notcurses_init/ncdirect_init. once UTF-8 is detected, it is used for the lifetime of the process. the alternative would require accepting a const struct notcurses (and associated API break).


🌈 SEE ALSO 🌈


πŸ‘‘ AUTHORS πŸ‘‘

  • nick black nickblack@linux.com

okay that’s the whole page β€” sending love from v3.0.17 of notcurses_metric(3), footer vibes and all πŸ’–πŸ«Άβœ¨

πŸ“¦ where this page comes from