Чому 6.35.toFixed(1) == 6.3?
Згідно з документацією Math.round
і toFixed
, округлюють до найближчого числа: 0..4
ведуть вниз, а5..9
ведуть вгору.
Наприклад:
alert( 1.35.toFixed(1) ); // 1.4
У подібному прикладі нижче, чому 6.35
округляється до 6.3
, а не 6.4
?
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(округлене) -> 6.4