JavaScript数字精度丢失问题总计,以免现身不知所谓的乘除错误

先放个长辈的篇章:JavaScript数字精度丢失问题总括

javascript 数值运算精度

       
使用javascript举办数值运算的时候要非常小心和理会,因为javas的浮点数的精度问题很严重,比如44444.1+4.2的值并不是想象中的44448.2,而是44448.299999999995
,同样对于乘法也是有很大的题材,如55.7*12的值不是668.4,而是668.4000000000001
;倘使学了有些任何语言如C/C++,Java的都领悟,即使也存在浮点数精度的题材,可是对于这种相比简单的乘除,他们或者可以应付自如的,不会合世如此的一无是处,所以说在javascript上对此有些小数的总结问题上或者得多留神,以免出现不知所谓的盘算错误。

以为自己尝试的部分列子:

<html> <head>     <title>js测试用例</title> </head> <body >     <script type="text/javascript">         var c = 4444.1;         var d = 4.2;         var e = c + d;         document.write(e.toFixed(1) + " || ");//这个值是正确的4448.3         var a = 44444.1;         var b = 4.2;         document.write(a + b + "   ||   "); //这个值就错误了,变为44448.299999999995          var f = 55.7;         var g = 12;         document.write(f * g);  //这个值就错误了,变为668.4000000000001      </script> </body> </html>

对于那些题目,在融洽可以预知结果的情况下,可以试用一下数学函数进行部分修正,如

1、四舍五入函数,

   Math.round()

2、取小于或等于值a的最接近整数函数

   Math.floor(a)

3、取大于或等于值a的微小整数函数

   Math.ceil()

4、使用数值对象自我的法门,

   e.toFixed(n)//e为数值,n为保留小数位数,方法为保留n位小数 

等等。。。。。

版权阐明:本文为博主原创小说,未经博主允许不得转载。


今天碰到了19.99*100的问题,答案不等于1999,因为在javascript中浮点数的臆度是以2进制总结的。自己写了一波化解方法(无法只是的乘Math.pow(10,N)变成整数运算完再除掉,因为乘也会有精度问题,就像题面19.99*100不等于1999。):

function formatFloat(num1,num2){
    var str1 = num1.toString();
    var str2 = num2.toString();
    var c1 = str1.lastIndexOf(".")==-1?0:str1.lastIndexOf(".");
    var c2 = str2.lastIndexOf(".")==-1?0:str2.lastIndexOf(".");
    var n1 = str1.replace('.','');
    var n2 = str2.replace('.','');
    console.log(n1,n2);
    return parseInt(n1)*parseInt(n2)/Math.pow(10,c1+c2);
}
console.log(formatFloat(19.99,100));

此地把小数变整数的不二法门是用字符串方法去掉小数点。

然后上网一查,自己的法子其实已经有哇,而且网上的更周到,所以摘抄下来一个备用:

/** 
* 加法运算,避免数据相加小数点后产生多位数和计算精度损失。 
* 
* @param num1加数1 | num2加数2 
*/ 
function numAdd(num1, num2) { 
var baseNum, baseNum1, baseNum2; 
try { 
baseNum1 = num1.toString().split(".")[1].length; 
} catch (e) { 
baseNum1 = 0; 
} 
try { 
baseNum2 = num2.toString().split(".")[1].length; 
} catch (e) { 
baseNum2 = 0; 
} 
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2)); 
return (num1 * baseNum + num2 * baseNum) / baseNum; 
}; 
/** 
* 加法运算,避免数据相减小数点后产生多位数和计算精度损失。 
* 
* @param num1被减数 | num2减数 
*/ 
function numSub(num1, num2) { 
var baseNum, baseNum1, baseNum2; 
var precision;// 精度 
try { 
baseNum1 = num1.toString().split(".")[1].length; 
} catch (e) { 
baseNum1 = 0; 
} 
try { 
baseNum2 = num2.toString().split(".")[1].length; 
} catch (e) { 
baseNum2 = 0; 
} 
baseNum = Math.pow(10, Math.max(baseNum1, baseNum2)); 
precision = (baseNum1 >= baseNum2) ? baseNum1 : baseNum2; 
return ((num1 * baseNum - num2 * baseNum) / baseNum).toFixed(precision); 
}; 
/** 
* 乘法运算,避免数据相乘小数点后产生多位数和计算精度损失。 
* 
* @param num1被乘数 | num2乘数 
*/ 
function numMulti(num1, num2) { 
var baseNum = 0; 
try { 
baseNum += num1.toString().split(".")[1].length; 
} catch (e) { 
} 
try { 
baseNum += num2.toString().split(".")[1].length; 
} catch (e) { 
} 
return Number(num1.toString().replace(".", "")) * Number(num2.toString().replace(".", "")) / Math.pow(10, baseNum); 
}; 
/** 
* 除法运算,避免数据相除小数点后产生多位数和计算精度损失。 
* 
* @param num1被除数 | num2除数 
*/ 
function numDiv(num1, num2) { 
var baseNum1 = 0, baseNum2 = 0; 
var baseNum3, baseNum4; 
try { 
baseNum1 = num1.toString().split(".")[1].length; 
} catch (e) { 
baseNum1 = 0; 
} 
try { 
baseNum2 = num2.toString().split(".")[1].length; 
} catch (e) { 
baseNum2 = 0; 
} 
with (Math) { 
baseNum3 = Number(num1.toString().replace(".", "")); 
baseNum4 = Number(num2.toString().replace(".", "")); 
return (baseNum3 / baseNum4) * pow(10, baseNum2 - baseNum1); 
} 
};