To: Peter Csizmadia Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Re: 2.4/3-2.4/3!=0 Date: Sun, 06 Nov 94 11:55:40 +0200 From: "Eli Zaretskii" > 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.