>> There is an easy way out of the suffix problem: use 'b?' for K, M, etc. 
>> and 'b?i' for Ki, Mi, ... so I don't see why there is so much debate 
>> about this. Forcing KiB, MiB, etc. will forcibly change the output of 
>> tools which currently display KB, MB, etc. using 2**(10**n) which may be 
>> undesirable.
> 
> No, it is desirable.  Are there tools which have declared that their
> output with scaled numbers is stable?  Even if there are, they don't
> have to be converted to use this function.  All new code should be
> forced to use suffixes which indicate the base.  Let's fix the world.

I figured out that with the 'u' modifier you CAN use the old method,
except with %A, which seems OK.. I have updated the spec to make
the IEEE/IEC prefix the default for binary conversion since it sounds
like everyone is converging toward following the new standard by
default.

See the updated spec below (there is an example and a NOTE describing
how to use the binary conversion and roll-your-own SI prefix for old
software converting to the new interface).

I also fixed the thousands grouping character modifier and made a few
other misc updates like replace suffix with prefix, etc..

- Eric

----------------
The release binding is patch; the stability level is Committed.
----------------

Standard C Library Functions                                    strfnum(3C)

NAME
        strfnum, strfunum - format a number as a scaled string

SYNOPSIS
        #include <string.h>

        int strfnum(char *restrict buffer, size_t buf_len,
        const char *restrict fmt, intmax_t value);

        int strfunum(char *restrict buffer, size_t buf_len,
        const char *restrict fmt, uintmax_t value);

DESCRIPTION
        The strfnum(), strfunum() functions will convert the integer
        <value> to a string, which will write at most <buf_len> bytes
        to the output <buffer>. The format of the output string is
        described by the <fmt> string.

     Conversion Specification
        The <fmt> string determines how <value> will be formatted to
        the output in a fashion similar to sprintf(). Each conversion
        specifier within the string consists of the % character, after
        which the following appear in sequence:

          o Zero or more of the following modifiers:
                '0' : the resulting string is zero padded.
                '-' : the resulting string is left aligned.
                '+' : the resulting string's first char is a
                      '+' if result is greater than zero.
                ' ' : the resulting string's first char is a
                      space is the result is greater than zero;
                      used only if the '+' modifier is not
                      defined.
                '#' : suppress trailing zeroes.
                ''' : include thousands' grouping character(s).
                'u' : suppress unit prefix.
           o An optional decimal length. If the result is smaller,
            the output will be padded according to the modifiers
            if present, otherwise the result will be space-padded.
          o An optional decimal precision, expressed as .# where
            # is an unsigned decimal integer. When not specified,
             three digits is the default precision.
          o An optional 'b' modifier, which will convert and
            express the result following the IEEE 1541-2002 standard
            (binary) rather than the default SI conversion (radix-10).
          o One conversion character from the following set:
                'A' : the unit is choosen automatically for the best
                      human-readable result. The integer part of the
                      result will be between 0 and 999 when radix-10
                      is used for the conversion, or 0 to 1023 when
                      radix-2 is used for the conversion.
                'N' : use no units for conversion (will divide by 1).
                'K' : use units of kilo or kibi. Will append the SI
                      prefix 'K' or the IEEE/IEC prefix 'Ki'.
                'M' : use units of mega or mebi. Will append the SI
                      prefix 'M' or the IEEE/IEC prefix 'Mi'.
                'G' : use units of giga or gibi. Will append the SI
                      prefix 'G' or the IEEE/IEC prefix 'Gi'.
                'T' : use units of tera or tebi. Will append the SI
                      prefix 'T' or the IEEE/IEC prefix 'Ti'.
                'P' : use units of peta or pebi. Will append the SI
                      prefix 'P' or the IEEE/IEC prefix 'Pi'.
                'E' : use units of exa or exbi. Will append the SI
                      prefix 'E' or the IEEE/IEC prefix 'Ei'.

        The sequence '%%' may be used to output literal % character.

RETURN VALUE
        The strfnum() function returns the number of bytes
        written into <buffer> if less than or equal to <buf_len>,
        otherwise returns the number of bytes that would have been
        written to <buffer> if <buf_len> had been sufficiently large.
        The value of <buf_len> may be passed as zero, and/or <buffer>
        may be a null pointer; this will result in a return value of
        the minimal-length buffer required to contain a complete
        result (minus a terminating NUL character).

EXAMPLES
        strfnum(buffer, len, "%5M", 123456789)
        will output "123.457M" into the buffer

        strfnum(buffer, len, "%5.M", 123456789)
        will output " 123M" into the buffer

        strfnum(buffer, len, "%5.0M", 123456789)
        will output " 123M" into the buffer

        strfnum(buffer, len, "%5.1M", 123456789)
        will output "123.5M" into the buffer

        strfnum(buffer, len, "%5.2M", 123456789)
        will output "123.46M" into the buffer

        strfnum(buffer, len, "%5.3M", 123456789)
        will output "123.457M" into the buffer

        strfnum(buffer, len, "%5.4M", 123456789)
        will output "123.4568M" into the buffer

        strfnum(buffer, len, "%+5.2K", 123456789)
        will output "+123456.79K" into the buffer

        strfnum(buffer, len, "%N", 123456789)
        will output "123456789" into the buffer.

        strfnum(buffer, len, "%'13.0N", 123456789)
        will output "  123,456,789" into the buffer.

        strfnum(buffer, len, "%'13.2N", 123456789)
        will output "123,456,789.00" into the buffer.

        strfnum(buffer, len, "%A", 0)
        will output "0.000" into the buffer.

        strfnum(buffer, len, "%bN", 0)
        will output "0.000" into the buffer.

        strfnum(buffer, len, "%bK", 0)
        will output "0.000Ki" into the buffer.

        strfnum(buffer, len, "%ubK", 1024)
        will output "1.000" into the buffer.

        strfnum(buffer, len, "FOO %0#5.4bA BAR", 1047552);
        will output "FOO 01023Ki BAR" into the buffer.

        strfnum(buffer, len, "FOO %'u0#5.4bAK BAR", 107552);
        will output "FOO 1,023K BAR" into the buffer.

NOTES
        The radix and thousands characters follow the
        current locale setting.

        To use the SI prefix for binary output, use the 'u'
        modifier and append the appropriate prefix. It is
        highly recommended that new software use the IEEE
        1541-2002 standard for expressing binary numbers.

ATTRIBUTES
        Interface Stability             Committed
        MT-Level                        Thread and async-signal safe

Reply via email to