[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: