Morten Welinder writes:
> > But, you are using a number in the range of 2^90, only
> > have 64 bits for storing the floating point representation, and
> > some of that is needed for the exponent.
> > 2^90 would require 91 bits for the base alone (as an integer
> > value), plus a couple more for the '*PI' portion, and then
> > more for the exponent. And that wouldn't include anything
> > past the decimal point.
> > You are more than 30 bits short of getting a crappy result.
>
> This is not right.
>
> Floating point variables are perfectly capable of holding _some_
> rather large floating point numbers completely accurately. The
> integer 2^90 is one of them (on a standard base-2 machine).
>
> It is true that its nearest neighbours are about 2^30 away, but
> that is not relevant for the accuracy of 2^90. pow(2.0,90.0)
> generates that value with no error.
>
> Therefore sin(2^90) is a well defined number somewhere between -1 and 1
> and the C fragment
>
> sin(pow(2.0,90.0))
>
> should calculate it with at most one wrong bit at the end. (You
> get a one-bit allowance since "sin" is trancendental.)
>
> Morten
> (who wouldn't be too surprised if some "sin" implementations failed
> to do that)
Me either. gcj, which has its own floating-point library, gets this
right:
System.out.println(Math.sin(Math.pow(2.0, 90.0)));
-0.9044312486086016
whereas gcc gets it wrong, at least on my GNU/Linux box:
printf ("%g %g\n", pow (2.0, 90.0), sin (pow (2.0, 90.0)));
1.23794e+27 -0.00536134
sin (2^90) is, approximately:
-.90443124860860158093619738795260971475
Andrew.