*TL;DR*
A friend mentioned that v8 might have accuracy optimizations built in for
integer arithmetic. Is this true?

*Long version:*
With:

var ts1 = 438877949516;
var ts2 = 438877949500;
var ts3 = 10.472319812098124124462;

does

(ts1 - ts2) + ts3

produce a result that's accurate to more digits than:

(ts1 + ts3) - ts2

*The reasoning for why it might not be more accurate*
Supposedly, all Javascript numbers are stored as 64 bit floating point
numbers. 64 bit floats are generally stored according to IEEE 754-1985
<https://en.wikipedia.org/wiki/IEEE_754-1985>, which means they're broken
up into 3 fields: a 1 bit sign, an 11 bit exponent, and a 52 bit
significand. This means that the number 438877949516 is actually stored as

             sign  exponent     significand
Binary       0     00000100101
 1.1001100010111100101010000011100100110000000000000000
Decimal      0           38           1.5966286792390747

You can get back to the original number with:

+1 * 1.5966286792390747 * 2^38 ≈ 438877949516

(Note: this ignores bias in the exponent, which doesn't really matter for
example purposes)

A fixed number of bits in the significand (52) essentially means that you
have a fixed number of binary significant figures. You can represent really
really big numbers, but that means that you lose fractional accuracy. How
many fractional binary significant figures you can provide is given by 52 -
floor(log2(N)). In the case of 438877949516, this means that we dedicate 38
bits to representing the scale of the number and we can only dedicate 14
bits to fractional accuracy, so the smallest difference between two numbers
as big as 438877949516 is 1/(2^14), or .00006104.

This means that ts1 - ts2 (i.e. 438877949516 - 438877949500) gives us a
number that's within .00006104 of 16. Add ts3 (10.472319812098124124462),
and our significant figure rules tell us that we still only have a number
within .00006104 of the true answer.

*The reasoning for why it might be more accurate*
If v8 has some optimization to do integer math exactly, then the story
changes. ts1 - ts2 (i.e. 438877949516 - 438877949500) now gives us an exact
answer of 16 with infinite fractional accuracy. We then add ts3
(10.472319812098124124462)
and, because numbers around 10 have a fractional resolution of 1/2^(52 -
floor(log2(10)) - about 1.7763568e-15 - we have a number that's about 10
orders of magnitude more accurate.

Woo! Sorry for the long explanation, but this is complicated stuff. Insight
is very much appreciated :)

-- 

Charlie Andrews |  Software Engineer |  [email protected]

-- 
-- 
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
--- 
You received this message because you are subscribed to the Google Groups 
"v8-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to