toFixed()和Math.round(),浮点数的精确运算

一、toFixed()

一般日常我们需要保留小数位数的时候,经常会使用到toFixed(),但toFixed()实际上并不是四舍五入(如果精确度要求不高,能用就用吧),而是叫银行家舍入法,大部分的编程软件使用的都是这种方法,也算是一种国际标准。

什么是银行家舍入法?

所谓银行家舍入法,其实质是一种四舍六入五取偶(又称四舍六入五留双)法。
其规则是:当舍去位的数值小于5时,直接舍去该位;当舍去位的数值大于等于6时,在舍去该位的同时向前位进一;当舍去位的数值等于5且(5后不为空且非全0)时,在舍去该位的同时向前位进一;当舍去的数值等于5且(5后为空或全0)时,如果前位数值为奇,则在舍去该位的同时向前位进一,如果前位数值为偶,则直接舍去该位。

简单的说,就是:四舍六入五考虑,五后非空就进一,五后为空看奇偶,五前为偶应舍去,五前为奇要进一。

以下是在Chrome浏览器下的计算结果,发现与上面的所说方法有所差异,那是因为浮点数造成的。至于细节可以戳这篇文章

toFixed(2).png

5后非空进1.png

二、Math.round()

网上很多人说可以使用Math.round()来解决四舍五入的问题,但是实际上以下图为例,当乘以100后,会存在浮点数问题,最后还是无法得到精确的结果


保留2位小数.png

浮点数.png

三、解决方法

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);   
                }   
            }

计算对比


image.png

你可能感兴趣的:(toFixed()和Math.round(),浮点数的精确运算)