@Wangww0925
2020-03-06T11:08:37.000000Z
字数 1481
阅读 394
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.02625.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 = thistypeof 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 = toDecimalString.prototype.toFixed = toDecimal"100".toFixed(); // 100.00"100".toFixed(0); // 100"100.005".toFixed(); // 100.01
作者 wendy
2019 年 1月 10日
