Paul Koning wrote:

"Scott" == Scott Robert Ladd <[EMAIL PROTECTED]> writes:

Scott> Richard Henderson wrote:
>> On Thu, May 26, 2005 at 10:34:14AM -0400, Scott Robert Ladd wrote:
>> >>> static const double range = PI; // * 2.0; static const double
>>> incr = PI / 100.0;
>> >> >> The trig insns fail with large numbers; an argument reduction loop
>> is required with their use.

Scott> Yes, but within the defined mathematical ranges for sine and
Scott> cosine -- [0, 2 * PI) -- the processor intrinsics are quite
Scott> accurate.

Huh?  Sine and consine are mathematically defined for all finite
inputs.
Yes, normally the first step is to reduce the arguments to a small
range around zero and then do the series expansion after that, because
the series expansion convergest fastest near zero.  But sin(100) is
certainly a valid call, even if not a common one.

          paul


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.

sin/cos/... is essentially based on the mod(n, PI) value.
To get 360 unique values, you need at least the 9 lower
bits of the number. You don't have them. That portion
of the number has fallen off the end of the representation,
and is forever lost. All you are calculating is noise.

To see this, try printing 'cos(n) - cos(n+1.0)'. If you get
something close to '0', you are outside of the functions
useful range, or just unluckey enough to be on opposite
sides of a hump (n*PI-1/2, and friends).

Or easier, try '(n + 1.0) - n'. If you don't get something
close to 1.0, you've lost.

$ vi check.c
#include <stdio.h>
#include <math.h>

#define PI 3.1415926535 /* Accurate enough for this test */

int main()
{
       double n = PI * pow(2.0, 90.0);

       printf("Test Add %f\n", (n+1) -n);
       printf("Test cos %f\n", cos(n) - cos(n+1));
}

$ gcc check.c  -lm
$ ./a.out
Test Add 0.000000
Test cos -0.000000

Reply via email to