Open the website inspector in Chrome (cmd + alt + i
or ctrl + shift + i
) and try the following:
javascript1.85 * 3 // 5.550000000000001
You are getting an error because JavaScript uses double-precision numbers. These numbers occupy 64 bits:
terminalS EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0 1 11 12 64
The value that you see after multiplying is calculated by the double-precision numbers formula:
Where s
is the sign, f
is the fraction, e
is the exponent and b
is the bias.
Going back to the previous example. Let's suppose that you want to generate the following decimal number:
javascriptlet v = 5.55
The closest binary number that generates the previous result would be:
terminal0 10000000001 0110001100110011001100110011001100110011001100110100 0 1 11 12 64
Let's demonstrate it by applying the previous formula and some JavaScript:
javascriptlet S = '0' let E = '10000000001' let F = '0110001100110011001100110011001100110011001100110100' // Normal conversion from binary to base 10 let s = parseInt(S, 2) // Normal conversion from binary to base 10 let e = parseInt(E, 2) // This is how to calculate the fraction of double precision numbers // The following line is equivalent to 0 · 2⁻¹ + 1 · 2⁻² + 1 · 2⁻³ + 0 · 2⁻⁴ + ... + 0 · 2⁻⁵² let f = [...F].reduce((acc, num, i) => acc += num * 2 ** (-(i + 1)), 0) // Let's define the bias (127 for 32 bits and 1023 for 64 bits) let b = 1023 // Applying the formula let v = (-1) ** s * (1 + f) * (2 ** (e - b)) // This is the final result // 5.550000000000001
Hi, I'm Erik, an engineer from Barcelona. If you like the post or have any comments, say hi.