Home / Blog / bugs

JS 浮点数运算精度问题

Author: Vic.Wang 2015/09/24 Tags:floatnumberMathjs精度问题运算浮点运算

JavaScript里面的浮点数是采用 IEEE754 FP 编码的,采用这种编码的语言都会有问题,比如C、C++、Java等都有问题,但是这些语言自身有标准类库来弥补,而JS却没有,所以就会掉坑里啦。

比如:
        0.1 + 0.2 === 0.30000000000000004
        1000000000000000128 === 1000000000000000129
        0.7 * 180 === 125.99999999998

是不是很诧异,0.1+0.2居然不等于0.3,没办法,这就是bug。

解决办法就是自己处理浮点数,下面是方法是网上的。

求和运算:

        function accAdd(num1, num2){
           var r1, r2, m;

           try{
               r1 = num1.toString().split('.')[1].length;
           }catch(e){
               r1 = 0;
           }

           try{
               r2 = num2.toString().split(".")[1].length;
           }catch(e){
               r2 = 0;
           }

           m = Math.pow(10, Math.max(r1, r2));

           return Math.round(num1 * m + num2 * m) / m;
        }
                    

相减运算:

        function accSub(num1, num2){
           var r1, r2, m;

           try{
               r1 = num1.toString().split('.')[1].length;
           }catch(e){
               r1 = 0;
           }

           try{
               r2 = num2.toString().split(".")[1].length;
           }catch(e){
               r2 = 0;
           }

           m = Math.pow(10, Math.max(r1, r2));
           n = (r1 >= r2) ? r1 : r2;

           return (Math.round(num1 * m - num2 * m) / m).toFixed(n);
        }
                    

相除运算:

        function accDiv(num1, num2){
           var t1, t2, r1, r2;

           try{
               t1 = num1.toString().split('.')[1].length;
           }catch(e){
               t1 = 0;
           }

           try{
               t2 = num2.toString().split(".")[1].length;
           }catch(e){
               t2 = 0;
           }

           r1 = Number(num1.toString().replace(".", ""));
           r2 = Number(num2.toString().replace(".", ""));

           return (r1 / r2) * Math.pow(10, t2 - t1);
        }
                    

相乘运算:

        function accMul(num1, num2){
            var m = 0,
                s1 = num1.toString(),
                s2 = num2.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);
        }
                    

想了解更多,看下面链接:

JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后

http://0.30000000000000004.com/