js精度丢失解决办法(浮点数产生的原因)[js教程]

web前端工作中经常遇到后端返回数据处理浮点数加减的问题,有时候浮点数的运算结果和我们预想的却不一样,先看个例子:

1、console.log(0.1+0.2);

JS教程

2、console.log(0.1+0.1);

明眼一看都觉得第1个应该是0.3,第2个应该是0.2;其实第1个实际上却不是0.3,而是0.30000000000000004,看控制台输出如下图所示:

图片[1]-js精度丢失解决办法(浮点数产生的原因)[js教程]-爱学社区

之所以偏离我们的预想是因为浮点数的精度问题导致。

一、浮点数产生的原因

首先就想到计算机能读懂的是二进制,在进行运算的时候,实际上是把数字转换为了二进制进行的,所以我们把0.1和0.2转换为二进制:

0.1 => 0.0001 1001 1001 1001..(无限循环)

0.2 => 0.0011 0011 0011 0011…(无限循环)

这里可以看出转换为二进制是一个无限循环的数字,单在计算机中对于无限循环的数字会进行舍入处理的,进行双精度浮点数的小数部分最多支持52位。然后把两个2进制的数进行运算得出的也是一个二进制数值,最后再把它转换为十进制。保留17位小数,所以0.1+0.2的值就成了 0.30000000000000004。 0.1+0.1的值成了0.20000000000000000,全是0的时候可以省略,就成了0.2。

二、精度丢失解决办法

爱学社区JS教程

JS

为了解决这个浮点数精度问题,我们可以把浮点数看成两部分,一个是整数部分,另一个是小数部分。整数部分加减肯定不会出现精度问题,剩下的是小数部分取两者最大的精度进行计算之后再按实际位数截取。下面给出写好的示例:

//比较
function floatCompare(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));
  var result = (arg1*m-arg2*m) >= 0 ? true : false;
  return result;
}

//加 
function floatAdd(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 floatSub(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 floatMul(arg1,arg2) { 
 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); 
} 
    
//除 
function floatDiv(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){} 
    
  r1=Number(arg1.toString().replace(".","")); 
  
  r2=Number(arg2.toString().replace(".","")); 
  return (r1/r2)*Math.pow(10,t2-t1); 
}

关注本站更多学习内容请收藏本站或保存本站永久网址[www.axue5.com]每天更新学习资源和各种,破解软件,福利美图技术教程,线报活动等网络资源!

------本页内容已结束,喜欢请分享------
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
相关推荐
评论 抢沙发

请登录后发表评论

    暂无评论内容