JS浮点计算误差的解决方案

有没有朋友们遇到过js中对于浮点计算有误差,如:console.log(0.1+0.2) = 0.30000000000000004

有没有朋友们遇到过js中对于浮点计算有误差,如:

console.log(0.1+0.2) =  0.30000000000000004

哈哈,很神奇,现在分享下如何解决这个问题,

用法如下:

jsFloat.add(num1,num2) //加

jsFloat.subtract(num1,num2) //减

jsFloat.mul(num1,num2) //乘

jsFloat.divide(num1,num2) //除

函数如下:(可以拷贝过去,也可以拷贝到一个js中引用到html中)

!function () {

//加法运算

    function addCalc(j1,j2){

        var numLen0=getPointBackLen(j1),//第一个值的的小数位数

            numLen1=getPointBackLen(j2),//第二个值的的小数位数

            maxLen=Math.max(numLen0,numLen1),//小数位数的最大值

            numLenDiff=0,//小数的差数

            num0Str='',//第一个值去掉小数点转字符

            num1Str='',//第二个值去掉小数点转字符

            operationReault=0;//返回计算后的值

        if(maxLen==0){

            operationReault=Number(j1)+Number(j2);

            return operationReault;

        }

        numLenDiff=numLen0-numLen1;

        num0Str=clearPoint(j1,".");

        num1Str=clearPoint(j2,".");

        //根据numLenDiff的正负来判断哪个数字的位数是短的,来走补全

        if(numLenDiff>0){

            num1Str=addZeroBack(num1Str,numLenDiff);

        }else if(numLenDiff<0){

            num0Str=addZeroBack(num0Str,Math.abs(numLenDiff));

        }

        //执行计算

        operationReault=addZeroFront((Number(num0Str)+Number(num1Str)).toString(),maxLen);

        return Number(operationReault.slice(0,-maxLen)+"."+operationReault.slice(-maxLen));

    }

//减法运算

    function subtractCalc(j1,j2){

        var numLen0=getPointBackLen(j1),//第一个值的的小数位数

            numLen1=getPointBackLen(j2),//第二个值的的小数位数

            maxLen=Math.max(numLen0,numLen1),//小数位数的最大值

            numLenDiff=0,//小数的差数

            num0Str='',//第一个值去掉小数点转字符

            num1Str='',//第二个值去掉小数点转字符

            operationReault=0;//返回计算后的值

        if(maxLen==0){

            operationReault=Number(j1)-Number(j2);

            return operationReault;

        }

        numLenDiff=numLen0-numLen1;

        num0Str=clearPoint(j1,".");

        num1Str=clearPoint(j2,".");

        //根据numLenDiff的正负来判断哪个数字的位数是短的,来走补全

        if(numLenDiff>0){

            num1Str=addZeroBack(num1Str,numLenDiff);

        }else if(numLenDiff<0){

            num0Str=addZeroBack(num0Str,Math.abs(numLenDiff));

        }

        //执行计算

        operationReault=addZeroFront((Number(num0Str)-Number(num1Str)).toString(),maxLen);

        return Number(operationReault.slice(0,-maxLen)+"."+operationReault.slice(-maxLen));

    }

//乘法运算

    function mul(c1,c2){

        var num0Len=getPointBackLen(c1),//第一个值的的小数位数

            num1Len=getPointBackLen(c2),//第二个值的的小数位数

            maxLen=Math.max(num0Len,num1Len),//取得小数位数中的最大数

            digitLen=0,//小数位数的统计值

            num0Str='',//第一个值去掉小数点转字符存偖

            num1Str='',//第二个值去掉小数点转字符存偖

            operationReault=0;//计算结果

        if(maxLen===0){//如果数字原本就是整形,直接执行计算

            operationReault=Number(c1)*Number(c2);

            return operationReault;

        }

        num0Str=clearPoint(c1,".");

        num1Str=clearPoint(c2,".");

        digitLen=num0Len+num1Len;//小数位数的总数

        operationReault=addZeroFront((Number(num0Str)*Number(num1Str)).toString(),digitLen);//对乘法运算后的结果执行位数补全

        return Number(operationReault.slice(0,-digitLen)+"."+operationReault.slice(-digitLen));

    }

//除法运算

    function divideCalc(c1,c2){

        var num0Len=getPointBackLen(c1),//第一个值的的小数位数

            num1Len=getPointBackLen(c2),//第二个值的的小数位数

            maxLen=Math.max(num0Len,num1Len),//取得小数位数中的最大数

            digitLen,//小数位数的统计值

            num0Str,//第一个值去掉小数点转字符存偖

            num1Str,//第二个值去掉小数点转字符存偖

            operationReault,//计算结果

            resultPointNum;//除法后结果的小数位数

        if(maxLen===0){//如果数字原本就是整形,直接执行计算

            operationReault=Number(c1)/Number(c2);

            return operationReault;

        }

        num0Str=clearPoint(c1,".");

        num1Str=clearPoint(c2,".");

        digitLen=num0Len-num1Len;//小数位数的差数

        operationReault=Number(num0Str)/Number(num1Str);

        if(digitLen==0){//如果除数,被除除数小数位相同,即直接返回计算值

            return operationReault;

        }

        resultPointNum=getPointBackLen(operationReault);//除法计算后可能的小数位数

        operationReault=clearPoint(operationReault,".");//除法运算结果去小数位数

        digitLen=digitLen+resultPointNum;//最后应该保留的小数位数

        if(digitLen>0){//如果要保留的小数位数不够

            operationReault=addZeroFront(operationReault,digitLen);//对计算的结果前补0

            return Number(operationReault.slice(0,-digitLen)+"."+operationReault.slice(-digitLen));

        }else {//如果要保留的小数位数小于0

            digitLen=Math.abs(digitLen);

            operationReault=addZeroBack(operationReault,digitLen);//对计算的结果后补0

            return Number(operationReault);

        }

    }

//后补0补够位数,str是当前的字符串,len是应该补的位数

    function addZeroBack(str,len){

        for(var i=0;i

            str=str+"0";

        }

        return str;

    }

//前置0补够位数,str是当前的字符串,len是处理后应该有的位数

    function addZeroFront(str,len){

        var getStr='',

            saveStr='',

            strLen=0,//存储当前字符串的长度

            addLen=0,//应该补位的个数

            returnStr='';

        //如果传进去的值是负值,那就要先存储符号

        if(str.indexOf('-')!=-1){

            getStr=str.replace('-','');

            saveStr='-';

        }else{

            getStr=str;

        }

        strLen=getStr.length;

        addLen=len-strLen;

        if(addLen<=0){

            returnStr=str;

        } else {

            for(var i=0;i

                getStr="0"+getStr;

            }

            returnStr=saveStr+getStr;

        }

        return returnStr;

    }

//取得小数位数

    function getPointBackLen(num){

        var returnLen=0;

        try {

            returnLen=num.toString().split(".")[1].length;//获取小数位数

        }catch(e){

            returnLen=0;

        }

        return returnLen;

    }

//浮点型数去小数点转字符串

    function clearPoint(num,str){

        var getStr=num.toString();

        if(getStr.indexOf(str)!=-1){

            return getStr.replace(str,"");

        }

        return getStr;

    }

//浮点数加减乘除法对象

    window.jsFloat={

        'add':addCalc,//加法运算

        'subtract':subtractCalc,//减法运算

        'mul':mul,//乘法运算

        'divide':divideCalc//除法运算

    };

}();

怎么样,好用吧,记得用完了回来点个赞,我一直都用它;

ps:好像浮点数除法有问题,没关系,分子分母同时乘以一个10的倍数吧分母变成整数就行了








你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
不写代码的码农
皮卡丘先生

交互动画课件制作

13 篇文章

作家榜 »

  1. 王倩 20 文章
  2. 苍老师 16 文章
  3. 大北兔 15 文章
  4. facaimao 14 文章
  5. 皮卡丘先生 13 文章
  6. 季梦导师 10 文章
  7. 许导解忧 10 文章
  8. 王迎保 10 文章