浮点型数据运算精度bug

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浮点型数据运算精度bug相关的知识,希望对你有一定的参考价值。

/**
         * 校验是否为数字
         * @param arg
         * @return
         */
        function checkIsNumber(arg){
            if(arg != null && arg.toString() != ""){
                var re = /^-?(0|[1-9]+\d*|[1-9]+\d*\.\d+|0\.\d+)$/;
                if(re.test(arg.toString())){
                    return true;
                }
            }
            return false;
        }

        /**
         * 加法函数,用来得到精确的加法结果
         * 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
         * 返回值注意:arg1和arg2可能是整数、浮点数、null、空字符串、其他字符串
         * @param arg1
         * @param arg2
         * @return
         */
        function accAdd(arg1,arg2){
            if(!checkIsNumber(arg1) || !checkIsNumber(arg2)){
                return null;
            }
            var r1,r2,m;
            try{r1=arg1.toString().split(".")[1].length;}catch(e){r1=0;} 
            try{r2=arg2.toString().split(".")[1].length;}catch(e){r2=0;} 
            m=Math.pow(10,Math.max(r1,r2));
            return (arg1*m+arg2*m)/m;
        }

        // 给Number类型增加一个add方法,调用起来更加方便。
        Number.prototype.add = function (arg){
            return accAdd(this,arg);
        }

        /**
         * 减法函数,用来得到精确的减法结果
         * 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
         * 返回值:arg1-arg2的值,arg1和arg2可能是整数、浮点数、null、空字符串、其他字符串
         * @param arg1
         * @param arg2
         * @return
         */
        function accSub(arg1,arg2){
            if(!checkIsNumber(arg1) || !checkIsNumber(arg2)){
                return null;
            }
            var r1,r2,m,n;    
            try{r1=arg1.toString().split(".")[1].length;}catch(e){r1=0;}    
            try{r2=arg2.toString().split(".")[1].length;}catch(e){r2=0;}
            m=Math.pow(10,Math.max(r1,r2));
            // n=(r1>=r2)?r1:r2; // 控制精度
            // return ((arg1*m-arg2*m)/m).toFixed(n);
            return (arg1*m-arg2*m)/m;
        }

        // 给Number类型增加一个subduct方法,调用起来更加方便。
        Number.prototype.subduct = function (arg){
            return accSub(this,arg);
        }

        /**
         * 除法函数,用来得到精确的除法结果
         * 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
         * 返回值:arg1除以arg2的精确结果
         * @param arg1
         * @param arg2
         * @return
         */
        function accDiv(arg1,arg2){
            if(!checkIsNumber(arg1) || !checkIsNumber(arg2)){
                return null;
            }
            var t1,t2,r1,r2;
            try{t1=arg1.toString().split(".")[1].length;}catch(e){t1=0;} 
            try{t2=arg2.toString().split(".")[1].length;}catch(e){t2=0;}
            with(Math){
            r1=Number(arg1.toString().replace(".",""));
            r2=Number(arg2.toString().replace(".","")); 
            return (r1/r2)*pow(10,t2-t1); 
            } 
        } 

        // 给Number类型增加一个div方法,调用起来更加方便。
        Number.prototype.div = function (arg){ 
            return accDiv(this,arg); 
        } 

        /**
         * 乘法函数,用来得到精确的乘法结果 
         * 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
         * 返回值:arg1乘以arg2的精确结果 
         * @param arg1
         * @param arg2
         * @return
         */
        function accMul(arg1,arg2) {
            if(!checkIsNumber(arg1) || !checkIsNumber(arg2)){
                return null;
            }
            var m=0,s1=arg1.toString(),s2=arg2.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类型增加一个mul方法,调用起来更加方便。
        Number.prototype.mul = function (arg){ 
            return accMul(this,arg); 
        } 
        
        console.log(accAdd(0.3,0.2)+" "+accSub(0.3,0.2))    

 

以上是关于浮点型数据运算精度bug的主要内容,如果未能解决你的问题,请参考以下文章

解决浮点型数值计算精度丢失的一种实现

java整形数据和浮点型数据

零基础学C语言知识总结二:基本的数据的表现形式与运算

零基础学C语言知识总结二:基本的数据的表现形式与运算

python怎么避免浮点精度问题

c语言中将一个浮点型赋值给整型时,会不会四舍五入?