5

When the following number is converted to a string and then split at the decimal point, the string that represents the decimal portion is incorrect. The expected value is 0123456789 but the value displayed in the console is 01234567.

const number = 123456789.0123456789;
console.log(number.toString().split("."));

If the number of digits to the left of the decimal is changed then what is displayed in the console for the decimal portion also changes but is not more than 8 characters for the testing I've done thus far. Why is it behaving like this? How can I get it to display the true string of digits that follow the decimal point?

EDIT -
After some trial and error testing, here are some additional findings -
When number = 2097151.0123456789 the decimal portion is correct.
When number = 2097152.0123456789 the decimal portion is incorrect.

knot22
  • 2,051
  • 2
  • 21
  • 40
  • 1
    Dot `(.)` is a regex _metacharacter_, representing any one character. If you want to split on literal dot, then escape it with backslash: `number.toString().split(/\./)` – Tim Biegeleisen Jun 14 '20 at 03:01
  • 6
    If you console just `number` before it even gets converted to a string, you'll see that it logs as the number `123456789.01234567`. I think you're running up against some kind of resolution limits of JS floats... – Alexander Nied Jun 14 '20 at 03:03
  • 1
    Does this [answer](https://stackoverflow.com/a/54803254/8943850) clear up your question? – Duc Nguyen Jun 14 '20 at 04:20

1 Answers1

0

The binary representation of a float in js consists of 64 bits, following the international IEEE 754 standard:

  • one sign bit,
  • 11 exponent bits and
  • 52 significant bits.

A number f is stored as f = s · m · 2^e, where s is either 1 or −1.

Because of the representation in the binary system there can be problems if floating numbers are finite in the decimal system (eg. 12,45) but periodic in the binary system (e.g. 1100,01110011001100110011001100...).
Due to the finite space, the number gets rounded. Sometimes this rounding can be reverted when reconverting to the decimal system; however, there are cases when this is not possible due to the insufficient precision (i.e. another number has the same representation).