Mail Archives: djgpp/1994/11/06/05:57:22
> main()
>{
> register double a1=2.4, b1=3.0;
> volatile double a2=2.4, b2=3.0;
> printf("2.4/3-2.4/3 = %le\n", a1/b1-a2/b2);
>}
>
> gcc a.c -lm -O1
> go32 a.out
> 2.4/3-2.4/3 = -3.70255041903800e-17
>
> Is it a normal effect of -O1? (a1=a2, b1=b2, a1/b1!=a2/b2)
As a general rule, floating point results should *never* be trusted
to be more accurate than a certain fraction of their magnitude.
This fraction is called ``machine epsilon'', and for double precision
64-bit numbers it is about 0.5e-16 (depends on the specifics of
the machine arithmetics). You can find this number with the help of
the following fragment:
double eps = 1.;
while ((eps + 1.) != eps)
eps /= 2.;
(Don't compile with -O, it might not work!)
More specifically, in your case -O1 switch causes the expression
with a1 and b1 to be computed at compile time, but the volatile
variables are only computed at run time. Probably, one of these
computations uses full 80-bit precision of the i386 FPU, while the
other is only stored with 64 bits of precision.
But whatever the specifics, the above general rule should be *always*
kept in mind.
- Raw text -