Bug#719015: Update: the magic number should be 1.9999999403953553
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;
}
Reply to: