javascript中toFixed使用的是银行家舍入规则。
银行家舍入:所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。
简单来说就是:四舍六入五考虑,五后非零就进一,五后为零看奇偶,五前为偶应舍去,五前为奇要进一。但是不论引入toFixed解决浮点数计算精度缺失的问题也好,它有没有使用银行家舍入法也罢,都是为了解决精度的问题,但是又离不开二进制浮点数的环境,但至少他帮助我们找到了问题所在,从而让我们有解决方法。
一:四舍五入并不是真正的四舍五入
这个问题是在测试阶段我们的测试人员提出来的。一开始我也很吃惊,结果待我在控制台试了一些数据之后,我懵逼了,我一直在用的toFixed方法竟然有问题
chrome上的测试结果:
1.35.toFixed(1) // 1.4 正确
1.335.toFixed(2) // 1.33 错误
1.3335.toFixed(3) // 1.333 错误
1.33335.toFixed(4) // 1.3334 正确
1.333335.toFixed(5) // 1.33333 错误
1.3333335.toFixed(6) // 1.333333 错误
IE上的测试结果:
1.35.toFixed(1) // 1.4 正确
1.335.toFixed(2) // 1.34 正确
1.3335.toFixed(3) // 1.334 正确
1.33335.toFixed(4) // 1.3334 正确
1.333335.toFixed(5) // 1.33334 正确
1.3333335.toFixed(6) // 1.333334 正确
我个人的解决方法numFormat 为千分位方法
numFormat(Math.round(money*100/100).toFixed(2))
第二种解决方法发现:
Number.prototype.toFixed = function(n) {
var power = Math.pow(10, n);
var fixed = (Math.round(this * power) / power).toString();
if(n == 0) return fixed;
if(fixed.indexOf('.') < 0) fixed += '.';
var padding = n + 1 - (fixed.length - fixed.indexOf('.'));
for(var i = 0; i < padding; i++) fixed += '0';
return fixed;
};298561.725.toFixed(2)
"298561.72"//5前为偶则舍去
Number.prototype.toFixed = function(n) {
var power = Math.pow(10, n);
var fixed = (Math.round(this * power) / power).toString();
if(n == 0) return fixed;
if(fixed.indexOf('.') < 0) fixed += '.';
var padding = n + 1 - (fixed.length - fixed.indexOf('.'));
for(var i = 0; i < padding; i++) fixed += '0';
return fixed;
};298561.715.toFixed(2)
"298561.72"//5前为奇则进一
第三种真正的四舍五入
可以用 tofixed (num, n) {
var symbol = 1
if (num < 0) {// 符号为负
symbol = -1
num *= -1
}
var num2 = (Math.round(num * Math.pow(10, n))
/ Math.pow(10, n) + Math.pow(10, -(n + 1)))
.toString().slice(0, -1)
return parseFloat(num2 * symbol).toFixed(n)
}
不进行四舍五入
字符串截取:String(22222.123456789).substring(0,String(22222.123456789).lastIndexOf('.')+5)
数值向下取整:(Math.floor(parseFloat(22222.123456789 * 10000)) / 10000).toFixed(4)
网友评论