1

I am creating a simple javascript array containing pre-calculated power of 2 values. That array has around 66 items, where each item contains a value so that it's power of two is calculated based on it's index. In example:

var the_array = [
    {name: 'blabla', index: 0, power: 1}, // 2^0
    {name: 'blabla', index: 1, power: 2}, // 2^1
    {name: 'blabla', index: 2, power: 4}, // 2^2
    // ...
    {name: 'blabla', index: 54, power: 18014398509481984}, // 2^54
    {name: 'blabla', index: 55, power: 36028797018963968}, // 2^55
    {name: 'blabla', index: 56, power: 72057594037927936}, // 2^56
    {name: 'blabla', index: 57, power: 144115188075855872}, // 2^57
    {name: 'blabla', index: 58, power: 288230376151711744}, // 2^58
    {name: 'blabla', index: 59, power: 576460752303423488}, // 2^59
    {name: 'blabla', index: 60, power: 1152921504606846976} // 2^60
];

I have checked the values in Google Chrome and Firefox, and all values are fine until 2^54. But for 2^55 and greater, the number is strangely rounded:

var the_array = [
    // ...
    {name: 'blabla', index: 54, power: 18014398509481984}, // 2^54 (fine)
    {name: 'blabla', index: 55, power: 36028797018963970}, // 2^55 (wrong, it should be 36028797018963968)
    {name: 'blabla', index: 56, power: 72057594037927940}, // 2^56 (wrong, it should be 72057594037927936)
    {name: 'blabla', index: 57, power: 144115188075855870}, // 2^57 (wrong, it should be 144115188075855872)
    {name: 'blabla', index: 58, power: 288230376151711740}, // 2^58 (wrong, it should be 288230376151711744)
    {name: 'blabla', index: 59, power: 576460752303423500}, // 2^59 (wrong, it should be 576460752303423488)
    {name: 'blabla', index: 60, power: 1152921504606847000} // 2^60 (wrong, it should be 1152921504606846976)
];

The same result can be confirmed on both browsers (Chrome and Firefox). Just open the console and enter the raw number "1152921504606846976" and hit enter, it should return the rounded number as an echo, no need for special functions.

My needs for this set of numbers are very specific, but I really would like to understand why Windows 10 calculator program can process those values without problems, while the browser cannot.

I have tried also with Opera Neon (64-bit) which (I understand) is based on Chromium and I receive the same results, so it looks like using 32-bit or 64-bit browsers makes no difference in this case.

I am using Windows 10 Pro, 64 bits; Google Chrome Version 57.0.2987.133 (32-bit), Firefox 52.0.2 (32-bit), and Opera Neon Version 1.0.2459.0 (64-bit).


I have realized that it is just a coincidence that 2^54 is kept correctly in Javascript; I have tried with 18014398509481983 (that is ((2^54) - 1)) and the browser console sets it again as 18014398509481984 (see the last digit). If I try with 18014398509481982 (that is ((2^54) - 2)) the value is kept correctly this time. This happens again in all mentioned browsers.

I am missing something here, though I cannot figure out what that may be.

David
  • 1,282
  • 3
  • 18
  • 40
  • 1
    Hint: [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) is 2^53 - 1 – Álvaro González Apr 10 '17 at 16:29
  • 1
    Well there is an upper limit [MAX_SAFE_INTEGER](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) beyond which all bets are off. – Alex K. Apr 10 '17 at 16:29
  • You may want to check [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken). It's a great starting point. – Álvaro González Apr 10 '17 at 16:51
  • A friend found this library: http://jsfromhell.com/classes/bignumber . It allows to work with big numbers beyond the browser's limitations, although it has to receive big numbers as string. That library seems to process arithmetic operations correctly on those numbers. This may be a way around the problem. What do you think about this? – David Apr 10 '17 at 17:13
  • 1
    Yes, a "Big Integer" library is the way to go, there are many; http://stackoverflow.com/questions/14531137/what-javascript-library-can-i-use-to-manipulate-big-integers – Alex K. Apr 10 '17 at 17:35

0 Answers0