вернуться к уроку

Почему 6.35.toFixed(1) == 6.3?

важность: 4

Методы Math.round и toFixed, согласно документации, округляют до ближайшего целого числа: 0..4 округляется в меньшую сторону, тогда как 5..9 в большую сторону.

Например:

alert( 1.35.toFixed(1) ); // 1.4

Но почему в примере ниже 6.35 округляется до 6.3?

alert( 6.35.toFixed(1) ); // 6.3

Как правильно округлить 6.35?

Во внутреннем двоичном представлении 6.35 является бесконечной двоичной дробью. Хранится она с потерей точности…

Давайте посмотрим:

alert( 6.35.toFixed(20) ); // 6.34999999999999964473

Потеря точности может как увеличивать, так и уменьшать число. В данном случае число становится чуть меньше, поэтому оно округляется в меньшую сторону.

А для числа 1.35?

alert( 1.35.toFixed(20) ); // 1.35000000000000008882

Тут потеря точности приводит к увеличению числа, поэтому округление произойдёт в большую сторону.

Каким образом можно исправить ошибку в округлении числа 6.35?

Мы должны приблизить его к целому числу, перед округлением:

alert( (6.35 * 10).toFixed(20) ); // 63.50000000000000000000

Обратите внимание, что для числа 63.5 не происходит потери точности. Дело в том, что десятичная часть 0.5 на самом деле 1/2. Дробные числа, делённые на степень 2, точно представлены в двоичной системе, теперь мы можем округлить число:

alert( Math.round(6.35 * 10) / 10 ); // 6.35 -> 63.5 -> 64(rounded) -> 6.4