Нам нужно пойти глубже, чтобы оно появилось первым…
ECMA-262 определяет Math.round()
следующим образом:
Возвращает числовое значение, которое являетсяближайший к аргументу и равен математическому целому числу. Если два значения целых чисел одинаково близки к аргументу, то результатом является значение числа, которое ближе к + ∞. Если аргумент уже является целым числом, результатом является сам аргумент.
Жирная часть важна, так как вы получите следующие результаты:
Math.round(1.674 * 100) / 100; // 1.67
Math.round(1.675 * 100) / 100; // 1.68 (wrong)
Math.round(1.676 * 100) / 100; // 1.68
Math.round(-1.674 * 100) / 100; // -1.67
Math.round(-1.675 * 100) / 100; // -1.67
Math.round(-1.676 * 100) / 100; // -1.68
Посмотрите, как это уже работает, как вы ожидаете для отрицательных чисел!
Если выхотите изменить 1.675
округленное значение, вы не можете использовать Math.floor()
, так как это изменит все остальные результаты:
Math.floor(1.674 * 100) / 100; // 1.67
Math.floor(1.675 * 100) / 100; // 1.67
Math.floor(1.676 * 100) / 100; // 1.67 (wrong)
Math.floor(-1.674 * 100) / 100; // -1.68 (wrong)
Math.floor(-1.675 * 100) / 100; // -1.68 (wrong)
Math.floor(-1.676 * 100) / 100; // -1.68
Мое решение будет использовать эту специфику Javascript, которую он ищет ближайшее значение к + ∞ .
- Возьмите ваше число
1.675
- Получите его абсолютное значение
1.675
(это для отрицательных чисел) - Отрицание
-1.675
- Используйте
round()
, чтобы получить наиболее близкое значение к + ∞ -1.67
- Отклонить его обратно, если изначально это было положительное число
1.67
Подтверждение концепции:
function _round(value, precision) {
var shift = Math.pow(10, precision);
var negateBack = Math.abs(value) / -value;
return Math.round(Math.abs(value) * -1 * shift) / shift * negateBack;
}
_round(1.674, 2); // 1.67
_round(1.675, 2); // 1.67
_round(1.676, 2); // 1.68
_round(-1.674, 2); // -1.67
_round(-1.675, 2); // -1.67
_round(-1.676, 2); // -1.68