

Trig functions on 64-bit floats are hard. - ColinWright
https://code.google.com/p/go/issues/detail?id=6794

======
raverbashing
This is the kind of story that takes you deep into the rabbit hole

Funny how people just don't bother with x87 anymore, even for things that it's
supposedly better. Oh btw x87 is not as exact as it could be for sin/cos,
because of backwards compatibility. (can't remember the reference right now,
but I remember Java computing them manually exactly because of this)

Still, if your program is asking for the cos of 2^120, you're doing it wrong,
as nicely explained here: " You need around 120 bits of 2pi to even start
getting significant bits of the cosine right, and you need 170 or so to get
them all right. Very few implementations bother, because this only matters if
you assume the argument was also accurate to at least 120 if not 170 or so
bits of precision, which at that magnitude is very unlikely."

~~~
stephencanon
Formally, math library functions should treat their inputs as representing
exact real-number values, not approximate ranges.

All good math library implementations hold themselves to a higher standard
than a naive backwards error bound you refer to. “Infinite-pi” range reduction
providing good relative accuracy for all inputs is used in the software
implementations of trig functions from Intel, NVIDIA, Apple, IBM, HP and Sun,
to name just a few companies, as well as most widely used third-party math
libraries, so it’s not really accurate to say that very few implementations
bother (though that would have been true 20 years ago). This can be done with
minimal performance impact for “normal” arguments, and not doing so today is
frankly pretty sloppy.

Implementing these operations via a naked FSIN or FCOS instruction is
especially horrific; even worse than using only ~67 bits of pi, those
instructions simply do not support arguments with an exponent larger than 63,
and on some architectures will simply return the input unchanged (i.e. the
result of sin(HUGE) will not even lie in [-1,1], which breaks all sorts of
invariants one would like to hold. For instance, asin(sin(x)) may then be NaN
for finite x, and sin^2(x) + cos^2(x) won’t be even _close_ to 1).

~~~
raverbashing
I agree you should try to do range reduction

But the question remains, that is, what is the cos(2^120) and what is the
cos(2^120+x) where x is the smallest increment representable in float64. Or
maybe a better question is how many times 2pi is in x.

~~~
stephencanon
> what is the cos(2^120)?

-0.92587902285…

> what is the cos(2^120+x) where x is the smallest increment representable in
> float64?

-0.72134636322…

> how many times 2pi is in x?

approximately 4.6974248 * 10^19.

All of these questions have well-defined answers. A good math library should
be able to help you compute them.

~~~
raverbashing
Thanks for computing those

Oh I don't argue about the mathematical exactitude of the values inside the
limited precision of float64 (or something else).

I doubt about the significance of them in a context other than (float) math.
Graphics, physics, etc.

Or better, don't try to numerically integrate cosine from 0 to 2^120 naively.

------
valarauca1
Generally speaking in floating points you have 'finite' accuracy. The best way
to think of floating points (for mortals), is to picture a 16 significant
digit number. You can only have 16 non-zero digits. Then a power that ranges
from 1020 to -1020.

Which means that when you have a value over ~1.6x10^16 you no longer have
values below the decimal point, and each 'step' you take will be larger then
an entire 2pi step of the trig cycle.

Its nice to think of floating points have infinite accuracy, and often times
nobody really thinks about what goes on inside of floating point numbers, but
in reality its a mess, a pure mess.

------
Houshalter
Once I tried to evolve approximations for trig functions with genetic
programming. It's surprisingly difficult but eventually I did get something
that sort of worked.

------
hahainternet
I believe this is essentially the perfect bug report and resolution. If only
every reported issue was like this.

