所有使用 IEEE 754 标准的编程语言,都存在浮点数运算的精度问题,不论是 C/C++、Java、Ruby,还是 Go、Python,当然 JavaScript/Node.js 也是如此。
更多语言的相关情况可以参考:https://0.30000000000000004.com 这个网站(网址挺有趣的)。
01
—
问题
以下是浮点数常见运算出现问题的示例:
0.1 + 0.2 = 0.30000000000000004 0.3 - 0.1 = 0.09999999999999998 19.99 * 100 = 1998.9999999999998 0.69 / 10 = 0.06899999999999999 0.7 ^ 2 = 0.48999999999999994
很显然没有哪个用户能够接受上面的运算结果,尤其是涉及到钱的计算。
02
—
解决
一般解决上述运算精度问题的主要思想是通过将浮点数运算转化为整数运算。
一、直接扩大缩小倍数
比如:
( 0.1 * 10 + 0.2 * 10 ) / 10 = 0.3
这种方式乍一看好像是转化成了整数运算,但其实也是存在问题的,因为其扩大倍数的时候仍然是浮点数运算,所以这种方式理论上是无法保证百分百 OK 的,但其优点在于处理简单,且在大多数情况下是行之有效的。
二、通过检测小数的位数转换为整数
上一种方式的软肋在于转换为整数的过程仍然是浮点数运算,然而这种完全是可以通过另一种途径解决。
const num = 1.23 ; // 得到其转换为整数至少需要扩大的倍数 num.toString(). split('.')[1].length ; //直接去掉小数点 num.toString().replace( '.' , '' ) ;
通过字符串方法转换为整数然后计算,这种方式比上一种稍微麻烦一点,但更加安全。
03
—
库
首先推荐使用 decimal.js 这个库(npm、github 搜索即可),能够满足绝大多数基本运算需求。
使用示例:
可以看到其常用的运算方法使用起来是比较简单的。
更多使用方法请自行参考官方文档(其接口与原生 Math 方法的含义是一致的)。
当然不得不提另一个库 mathjs ,这个库更加强大和复杂,不过我觉得 decimal.js 更轻量简单。
本文分享自 Node Python Go全栈开发 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!