解决JS两数相加的精度问题

| |
[不指定 2024/07/11 08:40 | by 刘新修 ]

JS中小数相加存在的精度问题

首先来看一段示例:

JavaScript代码
  1. console.log(0.1+0.2);//0.30000000000000004  
  2. console.log(0.2+0.7);//0.8999999999999999  

JS中两数小数相加产生精度问题的原因:

1、js中的数字类型只有number类型,不区分浮点型和整形,直接以浮点型double类型(双精度浮点类型)参与运算。

2、十进制数在做加减法运算前,首先转换为二进制类型再做相加减运算。

3、一些浮点数在转换为二进制数是会出现无线循环的情况,但由于double数据类型是以64位存储表示一个数据,其中第1位为符号位,第2位到第12位为指数位,其余52位为小数位,如此一来,一些浮点数转换为二进制产生无限循环的情况下,double类型数据只能存储64位,所以产生精度缺失问题。

解决办法

该方法仅为其中一个办法:

JavaScript代码
  1. <script>  
  2.         // 精确乘法计算  
  3.         function FloatMul(arg1, arg2) {  
  4.             var m = 0,  
  5.             s1 = arg1.toString(),//将第一个数据转换成字符出类型  
  6.             s2 = arg2.toString();//将第二个数据转换成字符出类型  
  7.             try {  
  8.             m += s1.split(".")[1].length;//截取数据的小数部分,得到小数位数  
  9.             } catch (e) {}  
  10.             try {  
  11.             m += s2.split(".")[1].length;//截取数据的小数部分,得到小数位数  
  12.             //将两个数据的小数位数长度相加  
  13.             } catch (e) {}  
  14.             var result = (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m);//将两个数扩大对应的小数位数倍转换成数字类型在相乘,乘完再除于对应的扩大倍数得到最终结果  
  15.             return isNaN(result) ? 0 : result;  
  16.         }  
  17.   
  18.         //获得两个小数相加的精确值  
  19.         const accountAdd = (arg1, arg2) => {  
  20.             let r1, r2, m;  
  21.             try {  
  22.             r1 = arg1.toString().split(".")[1].length;//将第一个数据转换成字符出类型,截取数据的小数部分,得到小数位数  
  23.             } catch (e) {  
  24.             r1 = 0;  
  25.             }  
  26.             try {  
  27.             r2 = arg2.toString().split(".")[1].length;//将第一个数据转换成字符出类型,截取数据的小数部分,得到小数位数  
  28.             } catch (e) {  
  29.             r2 = 0;  
  30.             }  
  31.             m = Math.pow(10, Math.max(r1, r2));//取出得到的最长位数,将10扩大最长位数倍  
  32.             return (FloatMul(arg1, m) + FloatMul(arg2, m)) / m;  
  33.         };  
  34.   
  35.         let sum = accountAdd(2.3443, -1.987);  
  36.         console.log(sum);//0.3573  
  37.     </script>  

思路:

1、先将两个小数数据用精确乘法扩大相同倍数,扩大后相加再处于扩大倍数得到最后结果。

H5/JS/CSS | 评论(0) | 引用(0) | 阅读(299)