2

Converting string to number produces incremented value:

var n = '9999999999999999';
console.log(n); // -> 9999999999999999
var nn = Number(n)
console.log(nn); // -> 10000000000000000

How to avoid this?

s.webbandit
  • 16,332
  • 16
  • 58
  • 82
  • 1
    How to avoid what? Arbitrary precision is a part of IEEE754, I suppose. – raina77ow May 10 '13 at 12:29
  • 1
    http://wtfjs.com/2010/07/22/magic-increasing-number – drinchev May 10 '13 at 12:37
  • @raina77ow how to avoid such behaviour? What should I do to get Number object with value of 9999999999999999? Or maybe how to check if number would be incremented? If I change `n` to `'999'` `Number` value is `999`. – s.webbandit May 10 '13 at 12:41
  • @PrasathK I can't. I'm taking this value from the input on HTML page. – s.webbandit May 10 '13 at 12:52
  • 1
    You cannot get JS Number with value of 9999999999999999 - for the same reasons you cannot store more than 256 different values in a single byte. One possible approach to solve this is to use ready-made libraries implementing `BigInteger` math - such as [jsbn.js](http://www-cs-students.stanford.edu/~tjw/jsbn/) – raina77ow May 10 '13 at 13:06

1 Answers1

2

9999999999999999 is treated internally in JavaScript as a floating-point number. It cannot be accurately represented in IEEE 754 double precision as it would require 54 bits of precision (the number of bits is log2(9999999999999999) = 53.150849512 and since fractional bits do not exist, the result must be rouned up) while IEEE 754 provides only 53 bits (1 implict bit + 52 explicitly stored bits of the mantissa) - one bit less. Hence the number simply gets rounded.

Since only one bit is lost in this case, even 54-bit numbers are exactly representable, since they nevertheless contain 0 in the bit, which gets lost. Odd 54-bit numbers are rounded to the nearest value that happens to be a doubled even 53-bit number given the default unbiased rounding mode of IEEE 754.

[Source]

Community
  • 1
  • 1
rekire
  • 47,260
  • 30
  • 167
  • 264