Search code examples
cprintf

Why doesn't %a format specifier display NaN payloads?


I use %a for outputting coefficients of fitted polynomials. Sometimes they go bad or denormal (but in this case it was due to a weird compiler fault). %f and %d report them as "nan" or "inf" (fair enough) but so does "%a" when it could just as easily display the hexadecimal representation of the actual mantissa. This can potentially contain useful information.

Hardware generated true nans have only a few distinct values whereas nans caused by over enthusiastic optimisers can have all sorts of peculiar values. Only experts are likely to use %a in anger so it might just as well display the thing in raw binary exponent form or alternately 0x1.xxxxxxnan.

Whilst it isn't much of a problem to print out the raw value in hexadecimal it took me by surprise that %a lost information when it processes a nan for output to the terminal. I always thought its purpose was to be able to represent in hexadecimal any floating point bit pattern saved to a file in human readable form and then reloaded into an FP variable on demand.


Solution

  • The output of the %a (or %A) format specifier when the corresponding argument is infinity or NaN is as you have described because the Standard says so.

    From this Draft C17 Standard:

    7.21.6 Formatted input/output functions


    Description

    8      The conversion specifiers and their meanings are:

    Then, in the second paragraph describing the a and A specifiers:

    A double argument representing an infinity or NaN is converted in the style of an f or F conversion specifier.

    Finally, in the paragraph describing the f and F specifiers:

    A double argument representing an infinity is converted in one of the styles [-]inf or [-]infinity — which style is implementation-defined. A double argument representing a NaN is converted in one of the styles [-]nan or [-]nan (n-char-sequence) — which style, and the meaning of any n-char-sequence, is implementation-defined. The F conversion specifier produces INF, INFINITY, or NAN instead of inf, infinity, or nan, respectively.