【问题标题】:Python: weird floating-point math results [duplicate]Python:奇怪的浮点数学结果
【发布时间】:2014-08-06 18:09:34
【问题描述】:
number = 9.3

while number % 0.5 != 0:
    number -= 0.1

print number

-20.0

我预计 number 最终会将此 while 循环保留为 9.0,但不知何故它变成了 -20.0。请注意,如果我将数字更改为 9.2,它会按预期工作并变为 9.0。有些值有效,例如 9.0、9.7,有些无效,例如 9.4、9.8。我不知道为什么。顺便说一句,9.8 变成了 -1204.5,这更奇怪。我无法解释这些结果。如果我刚刚开始学习计算机编程,因此遗漏了一些基本知识,请见谅。

【问题讨论】:

  • Floating point math 是问题所在。
  • 尝试改用fractions 模块。
  • 或者可能是decimal

标签: python math while-loop floating-point modulo


【解决方案1】:

这是因为浮点精度。如果你在循环中打印numbernumber % 0.5,你会得到类似:

9.2 0.2
9.1 0.1
9.0 1.7763568394e-15  # Not equal to 0!
8.9 0.4
8.8 0.3
8.7 0.2
8.6 0.1
8.5 3.5527136788e-15  # Still different from 0!
...

碰巧当number达到-20时,解是精确的:

-20.0 0.0

你应该做的是,检查结果是否足够小

EPSILON = 0.0001
number = 9.3
while number % 0.5 > EPSILON:
    number -= 0.1
print number

结果将是9.0


但是,如果您想要一个不涉及循环的 cleaner 解决方案,这将始终有效:

import math
number = 0.5 * math.floor(2.0 * number)

【讨论】:

  • 不,你真的应该首先避免累积舍入。
  • @tmyklebu 我不同意:也许 OP 在其循环中做一些其他需要临时值的简单减法。在每种情况下,用完全不同的解决方案来回答也无助于他理解问题。
  • 不同意所有你喜欢的,但不提倡基于与任意选择的 epsilon 进行比较的破坏解决方案。您可以对重复减法进行舍入误差分析,以证明对 epsilon 的特定(更严格)选择是合理的,或者您可以完全避免舍入。另请注意,如果 0.1 被替换为浮点表示大于用户天真的期望的数字,您的方法可能会中断。
  • @tmyklebu 用更干净的单线编辑了我的答案
猜你喜欢
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多