Floating point differences between platforms

NEW
Unassigned

Status

()

Core
JavaScript Engine
8 years ago
3 years ago

People

(Reporter: Philip Taylor, Unassigned)

Tracking

Trunk
x86
Linux
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

8 years ago
With a 32-bit Linux build of SM tip:

js> Math.exp(10)
22026.465794806725
js> Math.sin(Math.PI)
1.2246063538223773e-16
js> Math.cos(Math.PI/2)
6.123031769111886e-17
js> Math.tan(Math.PI)
-1.2246063538223773e-16
js> Math.atan2(1e-310, 2)
5e-311
js> Math.pow(Math.PI, -100)
1.9275814160560332e-50

With a 64-bit Linux build, all the answers are slightly different:

js> Math.exp(10)
22026.465794806718
js> Math.sin(Math.PI)
1.2246467991473532e-16
js> Math.cos(Math.PI/2)
6.123233995736766e-17
js> Math.tan(Math.PI)
-1.2246467991473532e-16
js> Math.atan2(1e-310, 2)
4.9999999999997e-311
js> Math.pow(Math.PI, -100)
1.9275814160560206e-50

Also I see some bigger differences between Linux and Windows (testing in Firefox 3.5 on both, since I don't have a convenient newer SpiderMonkey on Windows):

Math.tan(-1e300) = -4.802497308567303 (Linux), -4.987183803371025 (Windows)
(plus similar things with other trig functions)
1/((-0) % 1.5) = -Infinity (Linux), Infinity (Windows)

I'd personally like (for embedding) to have identical output for all conceivable inputs across 32- and 64-bit Linux, Windows and OS X (but I don't really care what output, and I could just delete some of the functions if necessary).

Comment 1

8 years ago
Adding our resident IEEE double gurus. The differences look like permitted rounding differences to me (we use the platform's FPU hardware, and its allowed to produce a 1-bit difference as per spec). Waldo, do you concur?

Comment 2

8 years ago
(In reply to comment #1)
> 1/((-0) % 1.5) = -Infinity (Linux), Infinity (Windows)

That looks like a bug in js_fmod from jslibmath.h
With respect to the function off-by-one differences:

ECMAScript never required precise behavior for any of these functions except for when given certain mathematically exact inputs or by specifying some quality of the result when given inputs comparing in a precise way to some mathematically exact boundary (mathematically exact inputs/boundaries: +0, -0, 1, -1, infinities, NaN, etc. but not Math.PI or similar approximate values).  None of these inputs here are exact in the necessary manner, so our behavior is permitted by ES3/ES5.

It would be nice to have exactly consistent results across architectures, but unless we revert back to a fdlibm-style implementation we use everywhere, I don't see it happening.  We're not going to munge FP mode so as to avoid or ensure extra precision for a least-significant digit difference.
I agree with comment 2.  (zero % finite) is clearly specified as zero for either zero value.

Comment 5

8 years ago
Yeah looking at #2 right now.

Comment 6

8 years ago
1/((-0) % 1.5) is -Infinity on my windows build with msvc8. Philip what version of ff did you use for testing this?
(Reporter)

Comment 7

8 years ago
I was using Firefox 3.5.3. But I just built a new version of the shell from Hg on Windows and can't reproduce the problem - I guess it was fixed in bug 503595, so that's okay.

The sin/cos/tan cases are not just least-significant-bit differences in the output, they differ around the 6th decimal digit. I accept they're not violating specs and are not behaving unreasonably, though.
We use libm these days. We used to use fdlibm for cross-platform consistency but it was slow compared to OS library implementations, and the code was crufty.

Are the sin/cos/tan differences legit? I crave a numerics-lawyer's opinion ;-).

/be
Hm, non-MSB differences are more sadmaking.  I don't think we should actually do anything about it for 1e-6-order differences, tho, at least not unless some more satisfactory solution than shipping our own unoptimized libm functions is possible.
(Assignee)

Updated

3 years ago
Assignee: general → nobody
You need to log in before you can comment on or make changes to this bug.