@Wangww0925
2020-03-06T11:08:37.000000Z
字数 1481
阅读 316
js
今天遇到一个很奇怪的问题 25.005.toFixed(2)
正常情况下我们都认为是 25.01
但实际情况是 25.00
, 下面讲述下这是为什么。
四舍六入五考虑,
五后非零就进一,
五后为零看奇偶,
五前为偶应舍去,
五前为奇要进一
PS:toFixed() 四舍五入的规则与数学中的规则不同,使用的是银行家舍入规则,银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法
四舍六入五考虑
25.024.toFixed(2); // "25.02", 小于5都舍弃
25.026.toFixed(2); // "25.03", 大于5都进一
五后非零就进一
25.0251.toFixed(2); // "25.03", 5后面不是0就进一为6,变成25.026
25.0250.toFixed(2); // "25.02", 5后面为0就舍弃
五后为零看五前奇偶
25.025.toFixed(2); // "25.02", 五前为偶应舍去
25.0250.toFixed(2); // "25.02", 五后为零但五前为偶应舍去
25.035.toFixed(2); // "25.04", 五前为奇要进一
25.0350.toFixed(2); // "25.04", 五后为零但五前为奇要进一
显然这样的规则不符合我们平常的数据处理,那么我们要怎样解决这个问题呢,我们知道Math.round()是四舍五入至整数,那么我们可以这样操作 Math.round(25.005 * 100) / 100
得到的是 25.01
/**
* 自定义数值转成指定小数位数
* num 数值
* digit 小数位数,默认2
*/
function toDecimal(digit = 2){
var num = this
typeof num == "string" ? num = parseFloat(num) : ""; // this如果是字符串,则转成数字类型
typeof digit == "string" ? digit = parseFloat(digit) : ""; // 参数digit如果是字符串,则转成数字类型
// 如果为NaN抛出异常
if(isNaN(num)) throw "传入 " + num + " 数值错误"
// 判断小数位数
var n = 1;
if(digit){
for(var i = 0; i < digit; i++){ n *= 10 }
};
// 数值进行四舍五入计算
var fixNum = (Math.round(num * n) / n).toString();
// 小数位数不足时,补全
if (digit != 0 && fixNum.indexOf(".") == -1) {
fixNum += ".";
}
while (digit != 0 && fixNum.split(".")[1].length < digit) {
fixNum += "0";
}
return fixNum; // 此处不能返回 parseFloat(fixNum),返回 parseFloat(fixNum) 会将 2.00 变成 2.
}
Number.prototype.toFixed = toDecimal
String.prototype.toFixed = toDecimal
"100".toFixed(); // 100.00
"100".toFixed(0); // 100
"100.005".toFixed(); // 100.01
作者 wendy
2019 年 1月 10日