On 4 February 2012 00:06, Vincent Lefevre <vincent+...@vinc17.org> wrote:
> 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.
>

Ok, so the value -0.85... seems to be the correct value.

If you convert all the doubles into long doubles.
You get:
gcc -O0 -c -o sincos.o sincos.c
gcc sincos.o -lm
sinl(10000000000000000000000.00000000000000000) = 0.46261304076460176
sinl(10000000000000000000000.00000000000000000) = 0.46261304076460176
gcc sincos.o -lm
gcc -O2 -c -o sincos.o sincos.c
sin(10000000000000000000000.00000000000000000) = -0.85220084976718880
sin(10000000000000000000000.00000000000000000) = 0.46261304076460176

So, I agree with Vincent Lefevre, my earlier statements are wrong.
There is definitely something going wrong either in gcc or libm.

Reply via email to