一、toFixed()
一般日常我们需要保留小数位数的时候,经常会使用到toFixed(),但toFixed()实际上并不是四舍五入(如果精确度要求不高,能用就用吧),而是叫银行家舍入法,大部分的编程软件使用的都是这种方法,也算是一种国际标准。
什么是银行家舍入法?
所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。
其规则是:当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后不为空且非全0)时,在舍去该位的同时向前位进一;当舍去的数值等于5且(5后为空或全0)时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。
简单的说,就是:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一。
以下是在Chrome浏览器下的计算结果,发现与上面的所说方法有所差异,那是因为浮点数造成的。至于细节可以戳这篇文章
二、Math.round()
网上很多人说可以使用Math.round()来解决四舍五入的问题,但是实际上以下图为例,当乘以100后,会存在浮点数问题,最后还是无法得到精确的结果
三、解决方法
1、引用库
Math.js
decimal.js
big.js
...
2、自己写方法
// 加法
Number.prototype.add = function(arg){
var r1,r2,m;
try{r1=this.toString().split(".")[1].length}catch(e){r1=0}
try{r2=arg.toString().split(".")[1].length}catch(e){r2=0}
m=Math.pow(10,Math.max(r1,r2))
return (this*m+arg*m)/m
}
//减法
Number.prototype.sub = function (arg){
return this.add(-arg);
}
//乘法
Number.prototype.mul = function (arg)
{
var m=0,s1=this.toString(),s2=arg.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
//除法
Number.prototype.div = function (arg){
var t1=0,t2=0,r1,r2;
try{t1=this.toString().split(".")[1].length}catch(e){}
try{t2=arg.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(this.toString().replace(".",""))
r2=Number(arg.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
计算对比