﻿# Неточные вычисления в JavaScript

> [HTML Version](js-imprecise-calculations.html)

Вычисление дробного числа в системе определяется особенностями исполнения языка JavaScript в браузере пользователя и в NodeJS на сервере.

В JavaScript число представлено в виде 64-битного формата IEEE-754, т. е. хранит значение с плавающей точкой, что может приводить к неточным вычислениям.

Например, следующее сравнение будет определено в JavaScript как ложное:

````
alert( 0.1 + 0.2 == 0.3 ); // false

````
Это связано с тем, что значение **0,3** в JavaScript вычисляется следующим образом:

````
alert( 0.1 + 0.2 ); // 0.30000000000000004

````
Происходит так потому, что число хранится в памяти как последовательность бит — единиц и нулей. И дроби в такой двоичной системе становятся бесконечной дробью.

В JavaScript не хранятся точные значения **0.1** или **0.2**. Числовой формат IEEE-754 округляет такие дроби до ближайшего возможного числа, например:

````
alert( 0.1.toFixed(20) ); // 0.10000000000000000555

````
Когда мы суммируем две дроби, их «неточности» тоже суммируются. 

Отметим, что ошибка в точности вычислений для чисел с плавающей точкой сохраняется в любом языке, где используется формат IEEE-754, включая PHP, Java, C, Perl, Ruby.

## Как решить проблему вычисления дробей

Можно попробовать полностью отказаться от дробей или использовать следующие способы.

1. Округлить результат вычисления с помощью метода `toFixed(n)`:

````
let sum = 0.1 + 0.2;  
alert( sum.toFixed(2) ); // 0.30

````
Метод `toFixed(n)` всегда возвращает строку, поэтому вы получите результат с заданным количеством цифр в десятичной части.

2. Временно умножить число на **100** (или большее), чтобы привести его к целому. Затем выполнить математические действия и разделить обратно на **100**. Суммируя целые числа, вы уменьшаете погрешность, но она всё равно появляется при финальном делении:

````
alert( (0.1 \* 10 + 0.2 \* 10) / 10 ); // 0.3  
alert( (0.28 \* 100 + 0.14 \* 100) / 100); // 0.4200000000000001

````
Таким образом, метод умножения и деления уменьшает погрешность, но полностью не решает её.