This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: weird optimization in sin+cos, x86 backend
- From: Vincent Lefevre <vincent+gcc at vinc17 dot org>
- To: Dominique Dhumieres <dominiq at lps dot ens dot fr>
- Cc: gcc at gcc dot gnu dot org, matz at suse dot de, konstantin dot vladimirov at gmail dot com
- Date: Sat, 4 Feb 2012 01:06:50 +0100
- Subject: Re: weird optimization in sin+cos, x86 backend
- References: <20120203164005.CD53D3BE18@mailhost.lps.ens.fr>
On 2012-02-03 17:40:05 +0100, Dominique Dhumieres wrote:
> While I fail to see how the "correct value" of
> cos(4.47460300787e+182)+sin(4.47460300787e+182)
> can be defined in the 'double' world, cos^2(x)+sin^2(x)=1 and
> sin(2*x)=2*sin(x)*cos(x) seems to be verified (at least for this value)
> even if the actual values of sin and cos depends on the optimisation level.
Actually this depends on the context. It is even worse: the value
of sin(some_value) depends on the context. Consider the following
program:
#include <stdio.h>
#include <math.h>
int main (void)
{
double x, c, s;
volatile double v;
x = 1.0e22;
s = sin (x);
printf ("sin(%.17g) = %.17g\n", x, s);
v = x;
x = v;
c = cos (x);
s = sin (x);
printf ("sin(%.17g) = %.17g\n", x, s);
return c == 0;
}
With "gcc -O" on x86_64 with glibc 2.13, one gets:
sin(1e+22) = -0.85220084976718879
sin(1e+22) = 0.46261304076460175
In the program, you can replace 1.0e22 by 4.47460300787e+182 or
whatever large constant you want. You'll get the same problem.
--
Vincent Lefèvre <vincent@vinc17.net> - Web: <http://www.vinc17.net/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.net/blog/>
Work: CR INRIA - computer arithmetic / AriC project (LIP, ENS-Lyon)