0

Складываю два десятичных числа и получаю: 0.30000000000000004

console.log(0.1 + 0.2); 

Я понимаю что так устроен js. Это его внутреннее представление чисел с плавающей точкой, на которое выделяется сколько то бит. Мой вопрос в следующем, какие надёжные техники , формальные и не формальные позволяют избежать подобных проблем.

spectre_it
  • 3,291

2 Answers2

2

Нашёл ответ:

Всё дело в том, что в стандарте IEEE 754 на число выделяется ровно 8 байт(=64 бита), не больше и не меньше.

Число 0.1 (одна десятая) записывается просто в десятичном формате. Но в двоичной системе счисления это бесконечная дробь, так как единица на десять в двоичной системе так просто не делится. Также бесконечной дробью является 0.2 (=2/10).

Двоичное значение бесконечных дробей хранится только до определенного знака, поэтому возникает неточность. Её даже можно увидеть:

alert( 0.1.toFixed(20) ); // 0.10000000000000000555

Когда мы складываем 0.1 и 0.2, то две неточности складываются, получаем незначительную, но всё же ошибку в вычислениях.

Есть два способа сложить 0.1 и 0.2:

  1. Сделать их целыми, сложить, а потом поделить:

alert( (0.1 * 10 + 0.2 * 10) / 10 ); // 0.3

  1. Сложить, а затем округлить до разумного знака после запятой. Округления до 10-го знака обычно бывает достаточно, чтобы отсечь ошибку вычислений:

var result = 0.1 + 0.2; alert( +result.toFixed(10) ); // 0.3

spectre_it
  • 3,291
1
parseFloat(0.1 + 0.2).toFixed(2);
C.Raf.T
  • 4,034