【问题标题】:Python : Float addition causing problems in conditional statement [duplicate]Python:浮点加法导致条件语句出现问题[重复]
【发布时间】:2016-02-06 02:03:32
【问题描述】:

这可能看起来很傻。但我是 python 新手,喜欢在我的程序中使用相等条件,并且遇到了一个非常令人惊讶的路障。虽然这里的实际问题是最后一个条件r==rmax 不满足,我会错过循环的迭代,但这并不是我担心的。

除了(微不足道的)解决方法之外,有人可以向我解释 简单来说发生了什么吗? (还有为什么无论我运行这个循环多少次,数字都一样,因此它是系统性的,而不是概率性的)。 以及确保不会发生这种情况的正确方法(我的意思是正确的意思是我应该在我的所有编码中采用一种编程实践,这样这种无意的差异就不会再发生)?我的意思是这样的循环是在我的代码中无处不在,这让我很担心。

似乎我不能相信 python 中的数字,这将使它作为计算工具毫无用处。 PS:我正在使用 Numpy 进行科学计算项目。

>>> while r<=r_max:
...     print repr(r)
...     r = r + r_step
...
2.4
2.5
2.6
2.7
2.8000000000000003
2.9000000000000004
3.0000000000000004
3.1000000000000005
3.2000000000000006
3.3000000000000007
3.400000000000001
3.500000000000001
3.600000000000001
3.700000000000001
3.800000000000001
3.9000000000000012

【问题讨论】:

  • 这主要是浮点运算的陷阱,在我看来不是 python。
  • 是的,浮动算术问题。但是在我年轻的时候,当我用 C++ 编程时,我经常在这样的循环中使用这样的条件,我从来没有遇到过这样的问题。我的意思是,这意味着,我以前(和将来)python 程序中的简单条件语句可能是错误的,因此会错过一些重要的迭代。在科学计算中,你不想犯这样的错误。
  • 我认为这与浮动的实际实现方式有关(在您年轻的时候,现在,浮动的处理方式可能会有所不同)。恕我直言,循环应该用 floating-point-gui.de/basic.
  • 是的,避免相等条件将是一个很好的实践。非常感谢 Pierre G。如何将您的评论标记为有帮助?

标签: python numpy while-loop floating-point conditional


【解决方案1】:

简单的答案是,通常在计算中表示的浮点数并不精确,您不能将它们视为精确。把它们当作模糊的;看看它们是否在某个范围内,而不是它们是否“相等”。

结果是相同的,因为它们都是确定性的。每次都以完全相同的方式进行计算。这不是随机错误的情况,而是机器以不精确的方式表示浮点数的情况。

Python 有一些精确的数据类型可以用来代替不精确的浮点数;查看decimalfractions 模块。

有一篇经典的文章叫做《每个计算机科学家应该知道的关于浮点运算的知识》;谷歌它并选择你喜欢的任何链接。

【讨论】:

  • 感谢您回答我的所有问题。
【解决方案2】:

这只是浮点运算的问题。实际上,如果您知道计算机内存中浮点数的表示,那么某些数字的表示虽然我们认为是整数,但并不是存储为整数。它仅以一定的精度存储(就小数点后的位数而言)。无论何时进行数学规划,这个问题都会一直存在。我建议你使用比较,它可以接受公差值。 Numpy 有这样的方法,便于比较。

【讨论】:

  • 嗨,谢谢。能否请您告诉我一些有助于与某些公差进行比较的 numpy 方法?
  • numpy.isclose(),numpy.allclose()。您可以在 docs.scipy.org/doc/numpy-dev/reference/generated/numpy.isclose.html 和 docs.scipy.org/doc/numpy/reference/generated/numpy.allclose.html 参考它们
  • 非常感谢您提供的信息。
  • 您没有将任何答案标记为正确,也没有投票赞成。您必须为您认为有用的答案投票。
  • 我已经对答案投了赞成票,但我需要 15 个声望才能公开投票。一直用stackoverflow,一个账号而已。
【解决方案3】:

皮埃尔 G. 是正确的。因为计算机以二进制计算数字,它不能准确地呈现很多浮点数。但它应该精确到某些数字取决于您使用的数据类型。

对于您的情况,我想也许您可以使用 round(number, digits) 函数来获取一个整数,然后进行比较。

【讨论】:

  • 感谢您的建议。但我认为添加这个round(number,digits) 可能会使代码不那么吸引人和拥挤。也许有更好的方法来解决这个问题(?)。
猜你喜欢
  • 1970-01-01
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-08
相关资源
最近更新 更多