5

This question wasn't asked on stackoverlow yet! I'm not asking why 0.1+0.2 doesn't equal 0.3, I'm asking very different thing! Please read the question before marking it as a duplicate.


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?

Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
  • It's not a duplicate, please read the question – Max Koretskyi May 20 '16 at 06:47
  • It's probably a duplicate of something else but not the one marked earlier. PLEASE READ THE QUESTION. This question is NOT ABOUT FLOATING POINT ADDITION. It is about PRECISION. – slebetman May 20 '16 at 06:48
  • This may be of interest though it does not exactly answer the question: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Number/toPrecision – slebetman May 20 '16 at 06:50
  • @slebetman, thanks, I'll take a look. This could give me a hint to understand the inconsistency – Max Koretskyi May 20 '16 at 06:55
  • Relevant section in the spec: http://www.ecma-international.org/ecma-262/6.0/#sec-tostring-applied-to-the-number-type – Robby Cornelissen May 20 '16 at 06:56
  • Generally when printing numbers js will convert it to string via the internal `.toString()` method but I couldn't find any documentation on the precision. Then I found `.toPrecision()` – slebetman May 20 '16 at 06:56
  • @RobbyCornelissen: Thanks for that. I was googling for it but couldn't find anything – slebetman May 20 '16 at 06:57
  • There is same question asked on https://www.toptal.com/javascript/interview-questions. And they say "Numbers in JavaScript are all treated with floating point precision, and as such, may not always yield the expected results." I don't know the proper source though. – mrk m May 20 '16 at 06:57
  • @mrkm, thanks, but the question asks very different thing) – Max Koretskyi May 20 '16 at 07:00
  • @RobbyCornelissen, thanks, I'll take a look – Max Koretskyi May 20 '16 at 07:00

2 Answers2

4

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 .
Ortomala Lokni
  • 56,620
  • 24
  • 188
  • 240
  • is that the maximum precision, can we get the number I ended up with using my function? – Max Koretskyi May 20 '16 at 06:59
  • cool, thanks. Can you please summarize in your answer what the guys in [this](http://stackoverflow.com/questions/37339683/why-console-log-shows-only-part-of-the-number-resulting-from-0-10-2-0-300000000#comment62196852_37339683) and [this](http://stackoverflow.com/questions/37339683/why-console-log-shows-only-part-of-the-number-resulting-from-0-10-2-0-300000000#comment62196830_37339683) comment said. I'll accept your answer – Max Koretskyi May 20 '16 at 07:08
2

Actually you don't have to write such a long question. What you could do is just open console and type:

var a = 0.3000000000000000444089209850062616169452667236328125;

console.log(a);

that would still give you result - 0.30000000000000004 (at least in Google chrome console).

And the reason why it is like that, is because limitations of JS, which only allow to show 16 chars of a float. You can read more in answer to this question: https://stackoverflow.com/a/19613321/3014041

Community
  • 1
  • 1
naneri
  • 3,771
  • 2
  • 29
  • 53