views:

770

answers:

1

Recently, sometimes (rarely) when we export data from our application, the export log contains float values that look like "-1.#J". I haven't been able to reproduce it so I don't know what the float looks like in binary, or how Visual Studio displays it.

I tried looking at the source code for printf, but didn't find anything (not 100% sure I looked at the right version though...).

I've tried googling but google throws away any #, it seems. And I can't find any lists of float errors.

+12  A: 

It can be either negative infinity or NaN (not a number). Due to the formatting on the field printf does not differentiate between them.

I tried the following code in Visual Studio 2008:

double a = 0.0;
printf("%.3g\n", 1.0 / a);  // +inf
printf("%.3g\n", -1.0 / a); // -inf
printf("%.3g\n", a / a);    //  NaN

which results in the following output:

1.#J
-1.#J
-1.#J

removing the .3 formatting specifier gives:

1.#INF
-1.#INF
-1.#IND

so it's clear 0/0 gives NaN and -1/0 gives negative infinity (NaN, -inf and +inf are the only "erroneous" floating point numbers, if I recall correctly)

Tobi
Interesting... I wonder why it ends up with a 'J' when truncating the infinity/NaN indicators?
Michael Burr
The J is the result of rounding the "digits" IN to one less place.
RBerteig
The translation of NaN and INF to a code with a leading digit and a dot is a IMHO a gross mistake. It is way too easy to end up with a numeric field in a text file that can be re-read (with an imperfect but plausible parser, admittedly) as the value +1 or -1 which is rather unlike the value that was printed. It would be much better to write it as +#INF, -#INF, and so forth.
RBerteig
@RBerteig: thanks for pointing out the rounding going on... As for the formatting, C90 seems to be silent on how Infinity and NaN should be formatted. C99 specifies that strings like "inf", "-inf", "nan" (or minor variations of those) must be used. Unfortunately, C99 is the bastard step-child of C/C++ language specs.
Michael Burr