It is well-known that 'double' computation results on x86 processors can
carry excess precision. Namely, if the value is stored in a floating-point
register (80 bits total, 64 bits mantissa) without passing through a
memory store, it can carry excess precision. The two ways to prevent
such excess precision (with GCC) are:
  - option -ffloat-store,
  - cast to 'volatile double'.

It is not so well-known that this phenomenon can also happen with 'float'
computations.

Here's a program:
======================================================================
#include <stdio.h>
#include <math.h>
int main ()
{
  printf ("%.12g\n", (double) 0.9272951f);
  printf ("%.12g\n", (double) 0.92729513f);
  printf ("%.12g\n", (double) 0.92729514f);
  printf ("%.12g\n", (double) 0.92729515f);
  printf ("%.12g\n", (double) 0.92729516f);
  printf ("%.12g\n", (double) 0.92729517f);
  printf ("%.12g\n", (double) 0.92729518f);
  printf ("%.12g\n", (double) 0.92729519f);
  printf ("%.12g\n", (double) 0.9272952f);
  printf ("%.12g\n", (double) 0.9272953f);
  printf ("\n");
  printf ("%.12g\n", (double) atan2f (0.8f, 0.6f));
  printf ("%.12g\n", (double) (float) atan2f (0.8f, 0.6f));
  printf ("%.12g\n", (double) (volatile float) atan2f (0.8f, 0.6f));
  return 0;
}
======================================================================

Output on mingw:

0.927295088768
0.927295148373
0.927295148373
0.927295148373
0.927295148373
0.927295148373
0.927295207977
0.927295207977
0.927295207977
0.927295327187

0.927295206081
0.927295206081
0.927295206081

You can see that there are no 'float' values between
0.927295148373 and 0.927295207977, yet the atan2f() function
- which is declared to return 'float' - has returned a value
between them.

Does anyone know whether this can also happen with glibc functions?
Or are glibc functions that return 'float' really returning 'float'
values?

Bruno
-- 
In memoriam Engin Ceber <http://en.wikipedia.org/wiki/Engin_Ceber>

Reply via email to