js浮点数精度问题的前世今生?

1.该问题出现的原因 ? 2.为何其他编程语言,比如java中可能没有chrome js console 中那么明显 3.大家在项目中踩过浮点数精度的…
关注者
221
被浏览
63,881

11 个回答

1. 主要问题是,你用十进制去想,0.7 是一个能准确表示的小数,而二进制却是循环小数0.1\dot{0}11\dot{0}。反过来想,就好像在三进制中 0.2 是一个很准确的数字,但在十进制中却是循环小数0.\dot{6}。除非用有理数表示,这些数字不能精确地用有限位的二进制表示,产生误差,0.7+0.1计算的结果也是有误差。把有误差的结果显示时,转换成十进位显示的算法发现该值与 0.8 相比,较接近 0.7999999999999999,所以显示后者。

2. 一些语言的预设输出数位是较小的,例如 C 的 printf("%f", x) 只显示小数后6位,Java 的PrintStream.format("%f", x) 也是小数后 6 位 。而 javascript 预设是最精确的输出,其他转换方式例如有

Number.prototype.toPrecision()

3, 4, 5. 问题太泛,恕不作答。

正好之前写过两篇文章:

-------------------------

1.该问题出现的原因 ?

浮点数 != 小数,之所以使用浮点数是在相同位数下对精度和范围的取舍

2.为何其他编程语言,比如java中可能没有chrome js console 中那么明显

对于浮点数的表示,几乎所有语言都一样,在我的文章“谁偷了你的精度”详细说明了浮点数的精度在个环节丢失了,以及为什么无法精确表示的小数却能够计算出精确的值。

3.大家在项目中踩过浮点数精度的坑?

---

4.最后采用哪些方案规避这个问题的?

涉及到精度要求高的场景,应该使用定点数表示小数。如 Java 中的 BigDecimal、C# 中的货币类型、MySQL 中的 NUMERIC 类型等。

5.为何采用改方案?

---