前言

对于这篇文章中记录的内容,不确定是否正确,毕竟这玩意儿不好验证。(比如文中提到“计算机打印机制会骗人”这一点)

查阅了一些资料以及 ChatGPT,得到的回复是这样的。所以就做了个简短的记录。

其实对于本篇提及的问题,我主要关注两点:

  1. 认识到问题的存在(能理解具体原因最好)
  2. 知道如何解决可能遇到的问题 👉🏻 如何判断两个浮点数的相等?

问题描述

python3
JavaScript

在学习很多编程语言时,提到浮点数,不少老师总是会提一嘴浮点数计算失真的问题。
但是蛮多老师都是非常快速地一嘴带过了。
意识到这个问题其实是一个普遍的问题,并不限于某种特定的编程语言,比如在 JavaScript、Python…… 中都存在,于是想要写一写自己对此的理解,下次学习其它编程语言遇到老师介绍这个问题时,直接跳过便是。

为什么有些浮点数计算失真有些不失真?

一句话总结:进制转换导致精度丢失,及计算机打印机制的欺骗

  1. 计算机存储数据采用的是二进制的形式,所以我们传递的十进制小数最终都要转为二进制形式进行计算
  2. 某些小数无法通过二进制精确的表示,计算机在使用二进制来表示这些小数时,会使用有限的空间来表示它们
    • 给的空间越多,自然就越是接近,但最终只能无限接近,永远不会相等
    • 就好比我们没法用小数来表示 1/3 一样,我们会使用 0.333333333333333333…… 这么一个无限循环小数来表示 1/3
  3. 计算机在计算完之后,我们获取到计算机计算后的结果,然后将其打印出来,这时候需要将二进制再转换为十进制,这又涉及到计算机的打印机制。对于一些计算结果 0.1 + 0.3 也许它们也是失真的,可是打印出来却是 0.4 符合我们预期的。这其实是计算机的打印机制让我们误以为结果是正常的,其实 0.1 + 0.3 的结果也可能有精度的损失,只是这个损失在二进制和十进制之间的转换中被四舍五入掉了

大部分都是会失真的,只不过有时候我们打印出来看到的结果,看似是没有失真罢了。

如何判断两个浮点数的相等?

不推荐直接比较两个浮点数是否相等,而是比较它们的差的绝对值是否小于一个非常小的数这样可以避免因为浮点数精度问题导致的错误结果

  1. # 不推荐的做法
  2. 0.1 + 0.2 == 0.3 # False
  3. # 推荐的做法
  4. (0.1 + 0.2) - 0.3 < 0.000000001 # True

遇到高精度的需求咋办?

不知道……

就日常业务中,还真没接触过类似的需求……

不同的语言找不同的工具来解决叭!

对于需要高精度小数计算的应用,通常需要采用特殊的数据结构和算法,例如使用定点数表示法,或者使用任意精度的数学库,如 Python 的 decimal 模块等。