Search code examples
javascriptbinaryieee-754

Why console.log shows only part of the number resulting from 0.1+0.2=0.30000000000000004


I've written this function that shows how JavaScript stores float numbers in 64 bits:

function to64bitFloat(number) {
    var f = new Float64Array(1);
    f[0] = number;
    var view = new Uint8Array(f.buffer);
    var i, result = "";
    for (i = view.length - 1; i >= 0; i--) {
        var bits = view[i].toString(2);
        if (bits.length < 8) {
            bits = new Array(8 - bits.length).fill('0').join("") + bits;
        }
        result += bits;
    }
    return result;
}

Now I want to check if the result of 0.1+0.2 is actually stored as it's shown in the console 0.30000000000000004. So I do the following:

var r = 0.1+0.2;
to64bitFloat(r);

The resulting number is:

0 01111111101 0011001100110011001100110011001100110011001100110100

Now, let's convert it to the binary:

Calculated exponent:

01111111101 = 1021
1021 - 1023 = -2 

Get it all together,

1.0011001100110011001100110011001100110011001100110100 x 2 ** -2 =
0.010011001100110011001100110011001100110011001100110100

Now, if we convert the resulting number into decimal using this converter, we get:

0.3000000000000000444089209850062616169452667236328125

Why doesn't console show the whole number, instead of just it's more significand digits?

Note on possible duplicates

I'm not asking why 0.1+0.2 doesn't equal 0.3, I'm asking a very different thing.


Solution

  • The console.log method is non-standard. In Firefox, you can specify the number of decimal with a format specifier

    console.log('%.60f', 0.1 + 0.2)
    

    gives

    0.300000000000000044408920985006261616945266723632812500000000
    

    Which is the same number as the one given by your converter.

    Note that, this doesn't work in chrome.

    In conclusion:

    • Javascript number are stored with the IEEE 754-2008 double-precision 64-bit binary format.
    • String representation of a number is defined in the ECMAScript standard.
    • console.log method is browser dependent and the Firefox implementation allows to specify an arbitrary number of decimal places to display numbers .