gpt4 book ai didi

python - Python 和一般情况下的浮点相等性

转载 作者:太空狗 更新时间:2023-10-29 16:54:07 25 4
gpt4 key购买 nike

我有一段代码的行为会有所不同,这取决于我是通过字典获取转换因子还是直接使用它们。

下面这段代码会打印1.0 == 1.0 -> False

但如果您将 factors[units_from] 替换为 10.0 并将 factors[units_to ] 替换为 1.0/2.54它将打印 1.0 == 1.0 -> True

#!/usr/bin/env python

base = 'cm'
factors = {
'cm' : 1.0,
'mm' : 10.0,
'm' : 0.01,
'km' : 1.0e-5,
'in' : 1.0 / 2.54,
'ft' : 1.0 / 2.54 / 12.0,
'yd' : 1.0 / 2.54 / 12.0 / 3.0,
'mile' : 1.0 / 2.54 / 12.0 / 5280,
'lightyear' : 1.0 / 2.54 / 12.0 / 5280 / 5.87849981e12,
}

# convert 25.4 mm to inches
val = 25.4
units_from = 'mm'
units_to = 'in'

base_value = val / factors[units_from]
ret = base_value * factors[units_to ]
print ret, '==', 1.0, '->', ret == 1.0

首先让我说,我很确定这里发生了什么。我以前在 C 中见过它,只是从未在 Python 中见过,但自从 Python 在 C 中实现后,我们就看到了它。

我知道 float 会改变从 CPU 寄存器到缓存再返回的值。我知道比较应该是两个相等的变量将返回 false,如果其中一个被调出而另一个留在寄存器中。

问题

  • 避免此类问题的最佳方法是什么?...在​​ Python 中或一般情况下。
  • 我做错了什么吗?

旁注

这显然是精简示例的一部分,但我想要做的是提供长度、体积等类,这些类可以与同一类但单位不同的其他对象进行比较。

修辞问题

  • 如果这是一个潜在的危险问题,因为它使程序的行为具有不确定性,编译器是否应该在检测到您正在检查 float 相等时发出警告或错误
  • 编译器是否应该支持用“足够接近”的函数替换所有浮点相等性检查的选项?
  • 编译器是否已经这样做了,我只是找不到相关信息。

最佳答案

如前所述,比较两个 float (或 double float 等)可能会出现问题。通常,与其比较是否完全相等,不如针对错误边界进行检查。如果它们在误差范围内,则认为它们相等。

说起来容易做起来难。 float 的性质使固定误差范围变得毫无值(value)。当值接近 0.0 时,小的误差界限(如 2*float_epsilon)工作良好,但如果值接近 1000 时会失败。对于值接近 0.0 的值,大到 1,000,000.0 的误差界限将太松散。

最好的解决方案是了解您的数学领域并根据具体情况选择合适的误差范围。

当这不切实际或您懒惰时,最后位置的单元 (ULP) 是一种非常新颖且可靠的解决方案。完整的细节比较复杂,你可以阅读更多here .

基本思路是这样的,一个 float 有两部分,尾数和指数。通常舍入误差只会将尾数改变几个步数。当该值接近 0.0 时,那些 steps 正好是 float_epsilon。当浮点值接近1,000,000时,步长将接近1。

Google test使用 ULP 到 compare floating point numbers .他们为要比较相等的两个 float 选择了 4 个 ULP 的默认值。您还可以使用他们的代码作为引用来构建您自己的 ULP 样式浮点比较器。

关于python - Python 和一般情况下的浮点相等性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3049101/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com