7

I faced problem and I can't quite explain it. Actually I'm quite surprised. When I try to increment the number 9933272057275866 by 1, it automatically adds 2!!! Please see following code:

let test = 9933272057275866;
let test2 = test+1;
console.log('Before:', test);
console.log('After:', test2);
console.log('Sub:', test2-test);

And respective output:

Before: 9933272057275866
After: 9933272057275868
Sub: 2

How can this be possible?

Environment is Javascript. I found this problem when I submitted a challenge at Hackerrank, then I also tried to do the same in my own environment on node.js. Same result!

What is happening?

Colin
  • 865
  • 1
  • 6
  • 23

1 Answers1

8

Basically, it's because 64 bits (*) aren't enough to represent the number accurately.

  • 4341 A521 1037 32ED: 9.933272057275866 ⨉ 1015
  • 4341 A521 1037 32EE: 9.933272057275868 ⨉ 1015

See how it skips one integer between them. In IEEE 754, the higher you go, the more the numbers are spread out along the number line. One thing to keep in mind is that floating point numbers are approximations. This is why you get this result:

0.1 + 0.2 === 0.3    // false

The max safe integer in IEEE 754 is 9007199254740991.

More fun facts with floating point arithmetics:

A + B == B + A              // true, commutative, except when A or B is NaN
(A + B) + C == A + (B + C)  // false, not associative

* It is worth mentioning that numbers in JavaScript (ECMAScript) are represented as 64 bit IEEE 754 doubles. ref

Derek 朕會功夫
  • 92,235
  • 44
  • 185
  • 247
  • 1
    More than `// false, not associative` shouldn't it be `// not always true, ...` – Kaiido Nov 16 '17 at 01:26
  • 1
    @Kaiido It's a mathematical statement, but it is a bit confusing when in it's in a code block instead of being some LaTeX formatted text. – Derek 朕會功夫 Nov 16 '17 at 01:27
  • @Kaiido For some reason LaTeX isn't supported on SO but it is on other SE sites. Unfortunately that's the best I can do. Just imagine it being formatted in some fancy LaTeX fonts ;) – Derek 朕會功夫 Nov 16 '17 at 01:31
  • Yes I was searching for the MathJax Syntax `$\...` implemented in mathoverflow, but indeed it doesn't seem to be supported in here... That already [has been asked](https://meta.stackexchange.com/questions/106281/mathjax-should-also-work-in-stackoverflow) numerous times, always to get rejected... – Kaiido Nov 16 '17 at 01:33