Sorry. The previous examples hit a discrepancy between strtof and strtod. The nearest float to 1.999999940395356f should be 0x1.0p+1f, rather than 0x1.fffffep+0f. If instead the number 1.9999999403953553f is used (see updated test case), then it correctly exposes the double rounding bug.
1.9999999403953553 is almost exactly between (float): 0x1.fffffep+0f 0x1p+1f but a little closer to the lower bound and thus rounds down when parsed as a float. It is between (double): 0x1.fffffefffffffp+0 0x1.ffffffp+0 but a little closer to the upper bound and thus rounds up when parsed as a double. Subsequent rounding to float then rounds up giving 0x1p+1f. Cheers, - Martin
/* ** gcc does not seem to handle (single precision) floating point constants correctly. ** I believe the closest single precision floating point number to: ** 1.9999999403953553f ** is ** 0x1.fffffep+0 ** which strtof correctly identifies, while gcc gives: ** 0x1p+1 ** which is out by 1 ulp. The likely cause for this is that the number is first parsed ** as a double and then rounded to a single precision number, giving a double rounding bug. */ #include <stdio.h> #include <stdlib.h> int main (int argc, char **argv) { float parsedAtCompileTime = 1.9999999403953553f; float parsedAtRunTime = strtof("1.9999999403953553f",NULL); printf("parsedAtCompileTime = %a\n",parsedAtCompileTime); printf("parsedAtRunTime = %a\n",parsedAtRunTime); printf("parsedAtCompileTime == parsedAtRunTime\t%d\n",(parsedAtCompileTime == parsedAtRunTime)); return 1; }