5

可能重复:
为什么十进制数不能用二进制精确表示?
程序没有进入 if 语句

所以我试图运行一个有两个变量的程序,当一个变量等于另一个变量时,它会执行一个函数。在这种情况下,打印垃圾邮件。但是,由于某种原因,当我运行这个程序时,即使我知道它们是相等的,我也没有得到任何输出。

g=0.0
b=3.0

while g < 30.0:
    if g==b:
        print "Hi"
    g+=.1
    print g, b
4

3 回答 3

9

您假设在 0.0 中添加足够的 0.1 次将产生 3.0。这些是浮点数,它们不准确。舍入误差使得该值永远不会完全等于 3.0。你几乎不应该用它==来测试浮点数。

于 2012-07-24T23:51:16.580 回答
6

做到这一点的一个好方法是使用整数值进行计数(例如,用 i 从 0 到 300 循环 1)并仅在使用浮点值时缩放计数器(例如,设置 f = i * .1)。当你这样做时,循环计数器总是精确的,所以你得到了你想要的迭代,并且只有一个浮点舍入,它不会在迭代之间累积。

循环计数器最常见的是整数类型,因此很容易看出加法是准确的(直到达到溢出)。但是,循环计数器也可以是浮点类型,前提是您确定它的值和操作是准确的。(常见的 32 位浮点格式精确地表示从 -2 24到 +2 24的整数。除此之外,它没有精确地表示整数的精度。它不能精确地表示 .1,所以你不能用增量来计数0.1. 但是你可以用 0.5、0.25、0.375 的增量或其他 2 的中等幂的小倍数来计算,这些都是精确表示的。)

于 2012-07-25T00:20:38.643 回答
0

为了扩展 Karoly Horvath 的评论,您可以做些什么来测试近似相等是选择一个相对于最小增量非常非常小的值(我们称之为 epsilon)。假设 epsilon 是 1.0 * 10^-6,比您的增量小五个数量级。(它可能应该基于浮点表示的平均舍入误差,但这会有所不同,这只是一个示例)。

然后你要做的是检查 g 和 b 是否小于 epsilon 不同 - 如果它们足够接近以至于它们实际上相等,那么实际上和实际之间的差异是舍入误差,你用 epsilon 来近似。

检查

abs(g - b) < epsilon

并且您将进行几乎但不完全相等的检查,这对于大多数用途来说应该已经足够了。

于 2012-07-25T00:28:36.047 回答