Open the website inspector in Chrome (`cmd + alt + i`

or `ctrl + shift + i`

) and try the following:

javascript`1.85 * 3 // 5.550000000000001`

You are getting an error because JavaScript uses double-precision numbers. These numbers occupy 64 bits:

terminal`S EEEEEEEEEEE FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 0 1 11 12 64`

- The first bit represents the sign of the number (S).
- The next eleven bits are the exponent bits (E).
- The final 52 are the fraction (F).

The value that you see after multiplying is calculated by the double-precision numbers formula:

$v = (-1)^s · (1 + f) · 2^{(e - b)}$

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:

javascript`let v = 5.55`

The closest binary number that generates the previous result would be:

terminal`0 10000000001 0110001100110011001100110011001100110011001100110100 0 1 11 12 64`

Let's demonstrate it by applying the previous formula and some JavaScript:

javascript`let 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.