По работе надо разобраться с javaScript. Есть функция .toFixed(2), которая округляет число до 2-х знаков после запятой. Вопрос состоит в том - каким способом она это делает, когда у нас 3 знак после запятой - 5-ка? (например 0.915, 1.235 и т.д.)
1) Сначала подумал, что простым округлением в большую сторону. Т.е.:
0.915 -> должно было перейти в 0.92
Проверяем:
- 0.905.toFixed(2) = 0.91 - ок
- 0.915.toFixed(2) = 0.92 - ок
- 0.925.toFixed(2) = 0.93 - ок
.....
- 0.955.toFixed(2) = 0.96 - false! JavaScript говорит = 0.95!
- 0.965.toFixed(2) = 0.97 - false! JavaScript говорит = 0.96!
Так. Округление в большую сторону не подходит.
2) Видимо функция работает следующим образом: от 0.905 до 0.945 мы увеличиваем в большую сторону, а с 0.955 до 0.995 просто отбрасывается 5-ка.
Проверяем:
- 0.905.toFixed(2) = 0.91 - ок
- 0.915.toFixed(2) = 0.92 - ок
- 0.925.toFixed(2) = 0.93 - ок
....
- 0.955.toFixed(2) = 0.95 - ок
- 0.995.toFixed(2) = 0.99 - ок
И все было хорошо, до тех пор, пока я не проверил на такое значение:
- 0.755.toFixed(2) = 0.75 - false! JavaScript говорит = 0.76!
- 0.765.toFixed(2) = 0.76 - false! JavaScript говорит = 0.77!
Думал может дело в не четности 7-ки? Поэтому такой результат. Но здесь я сломался окончательно:
- 1.755.toFixed(2) = 1.76 - false! (По предыдущему примеру) НО! JavaScript говорит = 1.75!
Отсюда вопрос - какой алгоритм работы метода .toFixed()?
Округляет он по обычным правилам, но неточно из-за операций над числами с плавающей запятой в бинарном формате - blog.chewxy.com/2014/02/24/what-every-javascript-d...
Округлять точно так: Math.round(0.955*100)/100
Что же там необычного?
"8a. Пусть n целое число, для которого значение n ÷ 10^f – х близко к нулю насколько возможно. Если таких n два, выбрать большее"
1.55 округлить до десятых:
n ÷ 10 − 1.55→0, должно быть -0.05 для n = 15 и 0.05 для n = 16, и выбрано 16, фактически -0.050000000000000044 и 0.050000000000000044 Выбирается правильное 16 и ставится точка в 1 знаке справа, получается 1.6
А для 2.55 получается -0.04999999999999982 для 25 и 0.050000000000000266 для 26, первое ближе к нулю, поэтому в итоге 2.5
Как только произвели арифметическую операцию не с целым числом, забудьте о точности. То, что разница не видна в десятичном значении не значит, что её нет в двоичном. Читали статью по ссылке? Все дроби в двоичном формате бесконечные. Плюс алгоритмы округления для уменьшения накопления ошибки.
Считать нужно целые, не превышающие безопасного значения.