JS中,在进行浮点数计算的时候,会出现精度丢失的问题,如下:
alert(0.1 + 0.2);
alert(0.3 - 0.2);
alert(0.1 * 0.2);
alert(0.3 * 0.2);
正常情况,得出的结果应该是0.3, 0.1, 0.02, 1.5, 但是实际得出的结果却不是这样,如下
可以看到,得出的结果并不是我们预期的结果,造成这样的原因就是浮点数丢失造成的,那么如何解决呢,通过已有的只是可以解决这个问题,如下:
浮点数加法精度丢失解决办法
分析:
1. 既然是浮点数进行加法运算造成的精度丢失,那么可不可以考虑换算成整数计算,再除以相同小数位呢
2. 获取小数位的长度,number.tostring().split('.')[1].length
3. 进行幂运算, Math.pow(10, Math.max(num1, num2))
4. 对进行算的数进行取整,再除以长度较大的幂次方
程序:
function accAdd(num1, num2){
var r1, r2, m;
try{
r1 = num1.toString().split('.')[1].length; //获取num1的小数位长度
}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; //将小数位转化成整数,再进行除法
}
alert(accAdd(0.1, 0.2)); //0.3
这样进行计算后,便可解决精度丢失问题
浮点数减法精度丢失问题
分析:
程序:
var r1, r2, m;
try{
r1 = num1.toString().split('.')[1].length; //获取num1的小数位长度
}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.toFixed( (r1>= r2) ? r1 : r2 ) ; //将小数位转化成整数,再进行除法
}
alert(accSub(0.3, 0.2)); //0.1
浮点数乘法精度丢失问题
分析:
程序:
function accMul(num1, num2){
var r1, r2, m = 0, s1 = num1.toString(), s2 = num2.toString();
try{
m += s1.split('.')[1].length;
}catch(e){}
try{
m += s2.split('.')[1].length; //获取两个数的小数位长度之和
}catch(e){}
//将num1和num2转化为字符串,去掉小数点,再强转成整数进行计算
return Number(s1.replace('.', ''))*Number(s2.replace('.',''))/Math.pow(10, m);
}
alert(accMul(0.1, 0.2)); //0.02
方法2:
程序:
var oStr=this.toString();
if(oStr.indexOf(".")==-1)//当为真时
return 1;
else
return Math.pow(10,parseInt(oStr.length-oStr.indexOf(".")-1));
}
function tran(){
var args=tran.arguments;
var temp=1;
/*
* 当i=0时,args[0]=0.1, args[0].rate()=10
* 当i=1时,args[1]=0.2, args[1].rate()=10
* */
for(var i=0;i<args.length;i++){
temp*=args[ i ]*args[ i ].rate();
}
for(var i=0;i<args.length;i++) {
temp /= args[i].rate();
}
return temp;
}
alert(tran(0.1, 0.2)); //0.02
浮点数除法精度丢失问题:
程序:
var r1, r2, s1 = num1.toString(), s2 = num2.toString();
try{
r1 = s1.split('.')[1].length;
}catch(e){
r1 = 0;
}
try{
r2 = s2.split('.')[1].length;
}catch(e){
r2 = 0;
}
return Number(s1.replace('.',''))/Number(s2.replace('.',''))*Math.pow(10, r2-r1);
}
alert(accDiv(0.3, 0.2)); //1.5
这就是解决浮点数精度丢失问题的办法,当然还有其他方法,核心思想其实就是转化为整数运算,再除以成小数位。