今天偶然间测试跟我说了一个bug,,我第一接触这个bug,接下来就描述一下这个问题,
后台返回的数据是下图所示:
但是我的处理就是*100+%,也就是转换成百分比的形式,但是结果却是这样的
百度一下才知道,原来是因为js处理浮点数存在bug问题,我目前熟悉的解决方案有两个;;;;
一、就是toFixed(),传统的使用四舍五入的方法,但是这种情况仅针对于对数据要求不严格。
二、首先将数值增大到整数,最后的结果再缩小增大的倍数。
console.log('a-b='+(a*10-b*10)/10);但是这个也有局限,,就是两个增大的倍数需要一样。
三、思路跟2的差不多,具体代码如下所示:
加法:
function accAdd(arg1,arg2){
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
}
减法:
function accSub(arg1,arg2){
return accAdd(arg1,-arg2);
}
乘法:
function Subtr(arg1,arg2){
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);
}
除法:
function accDiv(arg1,arg2){
var t1=0,t2=0,r1,r2;
try{t1=arg1.toString().split(".")[1].length}catch(e){}
try{t2=arg2.toString().split(".")[1].length}catch(e){}
with(Math){
r1=Number(arg1.toString().replace(".",""))
r2=Number(arg2.toString().replace(".",""))
return (r1/r2)*pow(10,t2-t1);
}
}
补充两点:
1.toFixed()问题
在chrome中。。toFixed不会进行四舍五入。。其中火狐也是。。解决方法
function toFixed(num, s) {
var times = Math.pow(10, s)
var des = num * times + 0.5
des = parseInt(des,10) / times
return des + ''
}
2.精度丢失问题
大整数的精度丢失和浮点数本质上是一样的,尾数位最大是 52 位,因此 JS 中能精准表示的最大整数是 Math.pow(2, 53),十进制即 9007199254740992。
大于 9007199254740992 的可能会丢失精度。。
但是在做一些项目的时候还是会遇到大整数的问题,
进行id的获取以及传值使用的时候,就会出现精度丢失问题,所以
这样的做法就是不用二进制直接传值过去,转成字符串的形式。