谨慎使用Number.prototype.toFixed()
今天在群里,leader发了一句这样的话:
上toFixed的MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed
但是MDN里却也用“四舍五入”来描述Number.prototype.toFixed()
,但是图里的又确实发生了,询问GPT后得知,这是一个常常易被忽略的特性。
这是因为 JavaScript 中的浮点数表示和四舍五入规则有时会导致一些意外的结果。具体来说,toFixed()
方法在处理四舍五入时遵循的是银行家舍入法(Bankers' Rounding),也称为“偶数舍入法”。这种方法的规则是:
- 如果舍入的数字正好在两个数之间(例如 1.55 和 2.55),则舍入到最接近的偶数。
在这个例子中:
1.55
四舍五入到最近的偶数是1.6
。【因为1.6比1.5更接近2(最近的偶数)】2.55
四舍五入到最近的偶数是2.5
。【因为2.5比2.6更接近2(最近的偶数)】
这种舍入方法的目的是在大量数据中减少舍入误差的累积。
如果需要始终按照传统的四舍五入规则(即四舍五入到最近的整数),我们可以使用其他方法来实现。例如:
function roundToFixed(num, decimalPlaces) {
var factor = Math.pow(10, decimalPlaces);
return (Math.round(num * factor) / factor).toFixed(decimalPlaces);
}
console.log(roundToFixed(1.55, 1)); // 输出 '1.6'
console.log(roundToFixed(2.55, 1)); // 输出 '2.6'
这个函数使用 Math.round() 来进行传统的四舍五入(它只留整数部分,所以先把小数点提上来,四舍五入后再降回去),然后再将结果格式化为指定的小数位数。这样可以避免银行家舍入法带来的意外结果。