This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: c/8395: gcc 2.95.4 and 3.2 generate wrong code for double onintel
- From: Bruce Allen <ballen at aei dot mpg dot de>
- To: gcc-gnats at gcc dot gnu dot org, gcc-prs at gcc dot gnu dot org, bernardo at sti dot uniurb dot it, gcc-bugs at gcc dot gnu dot org, nobody at gcc dot gnu dot org
- Date: Wed, 30 Oct 2002 18:25:15 +0100
- Subject: Re: c/8395: gcc 2.95.4 and 3.2 generate wrong code for double onintel
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=8395
There's nothing wrong here. It's very reasonable for this code to
produce ~10^-16 for double.
The reason is tha the number 1.2 can not be exactly represented as an
IEEE754 floating point number.
The numbers 5 and -6 CAN be exactly represented.
I suggest that you read the first 15 or so pages of "Numerical Recipes
in C" by Press, Teukolsky (and two others).
They discuss this question. Then look at
http://www.etsimo.uniovi.es/~antonio/uned/ieee754/IEEE-754.html
The closest IEEE754 double to 1.2 is (in binary)
1.0011001100110011001100110011001100110011001100110011
=
1.1999999999999999555910790149937383830547332763671875......
in decimal.
If we multiply this by 5 (which is exactly represented by an IEEE754
double) one gets
5.9999999999999997779553950749686919152736663818359375
which is not 6. The difference is what you are seeing.
#include <stdio.h>
int main(void)
{
double x, y, z;
long double lx, ly, lz;
x = -6.0;
y = -1.2;
z = 5;
printf("%g %g %g %g\n",
x,
y,
z,
x - y * z);
lx = -6.0L;
ly = -1.2L;
lz = 5L;
printf("%Lg %Lg %Lg %Lg\n",
lx,
ly,
lz,
lx - ly * lz);
return(0);
}