what is the longest possible string
how large does buf
need to be
Usual a string is assessed in length and the buffer size needed is 1 more than the length. The maximum length is discussed below. Add one for the size.
"%a"
has various implementation defined details. Because of that, code should be very careful about assuming the maximum length based on some calculation as below. Prudent code would handle a few extra characters.
Reasonable estimate: the sum of:
longest significand length, perhaps of the form -1.xxx...xxx where x is a hexadecimal digit. Assuming FLT_RADIX==2
: 1 /* sign */ + 2 /* 0x */ + 1 /* lead digit */ + 1 /* . */ + roundup((xxx_MANT_DIG-1)/4)
.
longest exponent which is a decimal power-of-2 for the value xxx_TRUE_MIN
or 1 /* p */ + 1 /* sign */ + roundup(log2(-xxx_MIN_EXP + xxx_MANT_DIG))
.
For common double
:
significand length: `1 + 2 + 1 + 1 + ru((53-1)/4)` --> 18
exponent length: `1 + 1 + ru(log10(- -1021 + 53))` --> 6
sum: 24
For common float
:
significand length: `1 + 2 + 1 + 1 + ru((24-1)/4)` --> 11
exponent length: `1 + 1 + ru(log10(- -125 + 24))` --> 5
sum: 16
Consider NANs may have payload formatted in some interesting fashion that exceeds the above sums.
Example: double
NAN w/payload: "-NAN4503599627370495"
. C specifies the payload and characters:[0-9A-Za-z_], but is silent on its length. One implementation used the payload as a decimal value.
1 /* sign */ + 3 /* NAN */ + 16 /* decimal digits = 20
A 52-bit payload reasonable is expected to have no more than 52 payload characters. I have never seen one longer than the above 20.
1 /* sign */ + 3 /* NAN */ + 52 /* binary digits = 56
C spec about "%a"
, "%A"
:
A double
argument representing a floating-point number is converted in the style [-]0xh.hhhhp±d, where there is one hexadecimal digit (which is nonzero if the argument is a normalized floating-point number and is otherwise unspecified) before the decimal-point
character) and the number of hexadecimal digits after it is equal to the precision; if the precision is missing and FLT_RADIX
is a power of 2, then the precision is sufficient for an exact representation of the value; if the precision is missing and FLT_RADIX
is not a power
of 2, then the precision is sufficient to distinguish values of type double
, except that trailing zeros may be omitted; if the precision is zero and the # flag is not specified, no decimal-point character appears. The letters abcdef are used for a conversion and the letters ABCDEF for A conversion. The A conversion specifier produces a number with X and P instead of x and p. The exponent always contains at least one digit, and only as many more digits as necessary to represent the decimal exponent of 2. If the value is zero, the exponent is zero.
A double
argument representing an infinity or NaN is converted in the style of an f or F conversion specifier.
C17dr § 7.21.6.1 8