Js浮点运算存在精度问题

Posted Bug—你很皮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Js浮点运算存在精度问题相关的知识,希望对你有一定的参考价值。

     记得在某一次项目中,运用js进行一系列算数运算,计算中会存在浮点类型,就单纯的进行了计算,最后在测试过程中,主管在核对数据的时候发现计算的结果是有问题的,于是就很纳闷,在网上搜索找到了答案  ,http://www.css88.com/archives/7340

      原因:计算过程中的十进制的数会先转换二进制,进行计算,然后将结果在转换为十进制(往往有些浮点类型数值转换为二进制是无穷的),所以往往也会导致出现精度问题

那么如何解决呢?

网上提供的方案如下:

  1 /**
  2  ** 加法函数,用来得到精确的加法结果
  3  ** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
  4  ** 调用:accAdd(arg1,arg2)
  5  ** 返回值:arg1加上arg2的精确结果
  6  **/
  7 function accAdd(arg1, arg2) {
  8     var r1, r2, m, c;
  9     try {
 10         r1 = arg1.toString().split(".")[1].length;
 11     }
 12     catch (e) {
 13         r1 = 0;
 14     }
 15     try {
 16         r2 = arg2.toString().split(".")[1].length;
 17     }
 18     catch (e) {
 19         r2 = 0;
 20     }
 21     c = Math.abs(r1 - r2);
 22     m = Math.pow(10, Math.max(r1, r2));
 23     if (c > 0) {
 24         var cm = Math.pow(10, c);
 25         if (r1 > r2) {
 26             arg1 = Number(arg1.toString().replace(".", ""));
 27             arg2 = Number(arg2.toString().replace(".", "")) * cm;
 28         } else {
 29             arg1 = Number(arg1.toString().replace(".", "")) * cm;
 30             arg2 = Number(arg2.toString().replace(".", ""));
 31         }
 32     } else {
 33         arg1 = Number(arg1.toString().replace(".", ""));
 34         arg2 = Number(arg2.toString().replace(".", ""));
 35     }
 36     return (arg1 + arg2) / m;
 37 }
 38  
 39 //给Number类型增加一个add方法,调用起来更加方便。
 40 Number.prototype.add = function (arg) {
 41     return accAdd(arg, this);
 42 };
 43 
 44 /**
 45  ** 减法函数,用来得到精确的减法结果
 46  ** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
 47  ** 调用:accSub(arg1,arg2)
 48  ** 返回值:arg1加上arg2的精确结果
 49  **/
 50 function accSub(arg1, arg2) {
 51     var r1, r2, m, n;
 52     try {
 53         r1 = arg1.toString().split(".")[1].length;
 54     }
 55     catch (e) {
 56         r1 = 0;
 57     }
 58     try {
 59         r2 = arg2.toString().split(".")[1].length;
 60     }
 61     catch (e) {
 62         r2 = 0;
 63     }
 64     m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
 65     n = (r1 >= r2) ? r1 : r2;
 66     return ((arg1 * m - arg2 * m) / m).toFixed(n);
 67 }
 68  
 69 // 给Number类型增加一个mul方法,调用起来更加方便。
 70 Number.prototype.sub = function (arg) {
 71     return accMul(arg, this);
 72 };
 73 
 74 
 75 /**
 76  ** 乘法函数,用来得到精确的乘法结果
 77  ** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
 78  ** 调用:accMul(arg1,arg2)
 79  ** 返回值:arg1乘以 arg2的精确结果
 80  **/
 81 function accMul(arg1, arg2) {
 82     var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
 83     try {
 84         m += s1.split(".")[1].length;
 85     }
 86     catch (e) {
 87     }
 88     try {
 89         m += s2.split(".")[1].length;
 90     }
 91     catch (e) {
 92     }
 93     return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
 94 }
 95  
 96 // 给Number类型增加一个mul方法,调用起来更加方便。
 97 Number.prototype.mul = function (arg) {
 98     return accMul(arg, this);
 99 };
100 
101 
102 /** 
103  ** 除法函数,用来得到精确的除法结果
104  ** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
105  ** 调用:accDiv(arg1,arg2)
106  ** 返回值:arg1除以arg2的精确结果
107  **/
108 function accDiv(arg1, arg2) {
109     var t1 = 0, t2 = 0, r1, r2;
110     try {
111         t1 = arg1.toString().split(".")[1].length;
112     }
113     catch (e) {
114     }
115     try {
116         t2 = arg2.toString().split(".")[1].length;
117     }
118     catch (e) {
119     }
120     with (Math) {
121         r1 = Number(arg1.toString().replace(".", ""));
122         r2 = Number(arg2.toString().replace(".", ""));
123         return (r1 / r2) * pow(10, t2 - t1);
124     }
125 }
126  
127 //给Number类型增加一个div方法,调用起来更加方便。
128 Number.prototype.div = function (arg) {
129     return accDiv(this, arg);
130 };

 

以上是关于Js浮点运算存在精度问题的主要内容,如果未能解决你的问题,请参考以下文章

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

解决“0.1 + 0.2 = 0.30000000000000004” - uniapp中JS浮点运算精度问题 - uniapp引入decimal.jsmath.js等数学库

JS浮点计算精度问题分析与解决

向量双双浮点运算

JS解决加减乘除浮点类型丢失精度问题