Javascript 中的浮点数精度丢失问题
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Javascript 中的浮点数精度丢失问题,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3093字,纯文字阅读大概需要5分钟。
内容图文
![Javascript 中的浮点数精度丢失问题](/upload/InfoBanner/zyjiaocheng/591/e066ea93e0cd4067bd2aece6af1c7937.jpg)
我们前端在做计算过程中,特别时小数的计算,都会遇到意想不到的结果,通常我们在价格的计算中遇到很多问题,这是由于 JS 中的 Number 类型是一个浮点类型。
在 chrome 中的运算结果
1 0.28 * 100 // 28.000000000000004 2 0.29 * 100 // 28.999999999999996 3 0.55 * 100 // 55.00000000000001 4 0.56 * 100 // 56.00000000000001 5 0.57 * 100 // 56.99999999999999 6 0.58 * 100 // 57.99999999999999 7 0.59 * 100 // 59 8 0.60 * 100 // 60
Nubmer 类型
我们先看看 JS 中的 Number 类型。它并不像其它的语言有不同的数字类型,例如:整型、长整型、浮点类型等等,定义不同的数字类型存储的空间也不一样。然而 JS 中的 Number 类型都是浮点类型并且存储空间为 8 数节(byte)(8*8 bit位)。其中Number 类型值的整数最多15位,小数最多17位。
精度问题
JS 中的 Number 是一个双精度浮点类型,双精度浮点类型在 64 位存储空间中的内容如下:
todo:
| 1位 | 11位 |52位 | |--------------:| -----------:|------:| | 符号位 | 指数位 | 小数位 | | 0表示正,1表示负 | -1022~+1023| 任意 |
由于计算机在计算的过程中,会把十进制数字先转换成二进制,然后做运算,因为浮点类型的小数位的限制而截断了运算完的二进制,这时候再把它转换成了十进制就产生了精度的问题。
举个例子: 0.1 + 0.2 = ?
- 0.1 转换成二进制:0.000110011001100110....
- 0.2 转换成二进制:0.001100110011001100....
- 0.000110011001100110.... + 0.001100110011001100.... = 0.0100110011001100110011001100110011001100110011001100...还很多,如果超过了 52 位就截断了。
- 然后转换成十进制:0.30000000000000004
解决方案
1.通过简单的四舍五入可以解决一些问题。
1 (0.1 + 0.2).toFixed(1);//0.3
但它也存在一些问题:
1 1.35.toFixed(1) // 1.4 正确 2 1.335.toFixed(2) // 1.33 错误 3 1.3335.toFixed(3) // 1.333 错误 4 1.33335.toFixed(4) // 1.3334 正确 5 1.333335.toFixed(5) // 1.33333 错误 6 1.3333335.toFixed(6) // 1.333333 错误
另外,它的返回结果类型是 String
。不能直接拿来做运算,因为计算机会认为是 字符串拼接
。
2.换算成整型计算
要彻底消除运算过程中的精度,需要将所有数字升位转化为整型了再做计算,计算完毕后再将最终结果进行相应的降位处理。
1 //除法 2 function accDiv(arg1,arg2){ 3 var t1=0,t2=0,r1,r2; 4 try{t1=arg1.toString().split(".")[1].length}catch(e){} 5 try{t2=arg2.toString().split(".")[1].length}catch(e){} 6 with(Math){ 7 r1=Number(arg1.toString().replace(".","")) 8 r2=Number(arg2.toString().replace(".","")) 9 return accMul((r1/r2),pow(10,t2-t1)); 10 } 11 } 12 //乘法 13 function accMul(arg1,arg2) 14 { 15 var m=0,s1=arg1.toString(),s2=arg2.toString(); 16 try{m+=s1.split(".")[1].length}catch(e){} 17 try{m+=s2.split(".")[1].length}catch(e){} 18 return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m) 19 } 20 //加法 21 function accAdd(arg1,arg2){ 22 var r1,r2,m; 23 try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 24 try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 25 m=Math.pow(10,Math.max(r1,r2)) 26 return (arg1*m+arg2*m)/m 27 } 28 //减法 29 function Subtr(arg1,arg2){ 30 var r1,r2,m,n; 31 try{r1=arg1.toString().split(".")[1].length}catch(e){r1=0} 32 try{r2=arg2.toString().split(".")[1].length}catch(e){r2=0} 33 m=Math.pow(10,Math.max(r1,r2)); 34 n=(r1>=r2)?r1:r2; 35 return ((arg1*m-arg2*m)/m).toFixed(n); 36 }
内容总结
以上是互联网集市为您收集整理的Javascript 中的浮点数精度丢失问题全部内容,希望文章能够帮你解决Javascript 中的浮点数精度丢失问题所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。