开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情
背景
实话实讲,从业三年,一直听说过、也看到过js精度丢失带来的一些问题。但是自己还从未遇到,因为一直不涉及这样大数据的处理逻辑。但是今天,被领导安排了一个bug。一看现象就是精度问题。于是决定用该文记录下。
问题
其实这个问题的表现很简单,就是当用户输入96.00003的时候。input输入框的内容就变成了96.00003000000002000。代码实现主要是在计算幂的时候,使用了Math.pow(10, -5)。这样的话,输出的结果就不是0.00001,而是0.000009999999999999999。因此,在接下来与其他大数据相乘的时候就造成了上面的精度持续丢失。
方案
要说如何解决浮点数运算的精度问题,大体有 3 种思路:
- 考虑到每次浮点数运算的偏差非常小(其实不然),可以对结果进行指定精度的四舍五入,比如可以parseFloat(result.toFixed(12))。在大多数情况下,它可以得到正确结果,但是对一些极端情况,toFixed 到 12 是不够的。
- 将浮点数转为整数运算,再对结果做除法。比如0.1 + 0.2,可以转化为(1*2)/3。比如 number-precision 这个库就是使用的这种方案,但是这也是有问题的,
- 把浮点数转化为字符串,模拟实际运算的过程。目前已经有了很多较为成熟的库,比如 decimal.js,bignumber.js,以及big.js等。
总结和收获
通过一个工作上遇到的问题,从表现到代码实现的问题,再到收集到的网上方案。希望可以帮助大家在遇到精度的问题时,能够看到本文就一下解决掉。