【问题标题】:Why is 5 != 5.0000000000000000001 False, but 5 != 5.00000001 True? [duplicate]为什么 5 != 5.0000000000000000001 为假,但 5 != 5.00000001 为真? [复制]
【发布时间】:2016-12-21 20:36:17
【问题描述】:

在 python 3.5 中,我只是在玩比较运算符并遇到了这个(看似)奇怪的问题。

由于浮点值固有的不准确性,解释器决定不考虑相关值的小数点后零的数量是否存在阈值?

【问题讨论】:

  • @BilltheLizard,我认为问题不同,因为上下文是比较运算符,尽管它显然是相关的。在这种情况下,我要问为什么 python 无法确定 5.0000000000000000001 不是 5,而不是为什么 python 在计算 FPV 时返回近似值。不确定是否值得立即投反对票……(不是说是你,但无论是谁,最好能得到解释)。
  • @jeremyradcliff 好吧,它们不是字符串,所以显然(隐式)有一个解析步骤。由于它们成为真正的浮点数,因此它们被限制在该精度范围内。
  • @harold,谢谢,这很有道理。
  • 如果您愿意,请查看float_richcompare 他负责此操作。我通常认为这是一个不错的问题。
  • @JimFasarakis-Hilliard,谢谢。掌握该功能中的所有内容可能超出了我目前的技能,但我认为通过慢慢了解并尝试仍然可以获得很多。

标签: python python-3.x floating-point precision comparison-operators


【解决方案1】:

简而言之,在完成输入解析的阶段,Python 需要将您的输入转换为 C double,然后可以将其转换为 Python float。具有更多than 16 decimal digits 的输入将被近似,5.0000000000000001 被近似为5.0

>>> 5.0000000000000001 
5.0

因此,5 == 5.0000000000000001 的比较将成功(5 将被转换为等于5.0 的 Python 浮点数,以便进行比较)。

对于小于上述数字的数字,结果(可以表示)并说明一切:

>>> 5.000000000000001
5.000000000000001

是的,float_richcompare ——不幸的是——与我在对该问题的原始评论中所认为的这种行为无关。这一切都发生在它被调用之前。

【讨论】:

  • 感谢您写出完整的答案,这很有帮助;我不知道 python 正在经历将输入转换为 C 双精度的过程。
  • 为什么“不幸”?你肯定不希望浮点数的相等比较来做某种模糊比较:它会弄乱相等的传递性,因此会混淆 set 和 dict 包含等。
  • @MarkDickinson 我最初虽然这是float_richcompare 所做的,即我错过了`5.0000000000000001` 将被float_new 近似为5.0;。我以为这发生在richcompare。 “不幸的是”指向我在问题下的“摇摆不定”评论:-)
  • 嗯,不是 any 输入超过 16 位:例如,5.0000000000000005 不是 5。
  • @RickRegan 措辞模棱两可,更新以更好地描述我的意思。
猜你喜欢
  • 1970-01-01
  • 2019-08-09
  • 2023-04-02
  • 2012-06-12
  • 2017-06-18
  • 2015-12-05
  • 2021-05-25
  • 1970-01-01
  • 2014-02-03
相关资源
最近更新 更多