【问题标题】:Python not dealing with small numbers correctly [duplicate]Python没有正确处理小数字[重复]
【发布时间】:2016-04-11 00:51:23
【问题描述】:

我正在尝试制作一个 python 脚本,但无法使其正常工作。我正在处理非常小的数字,python 似乎不喜欢它。这是我的脚本:

x = 0
while x < 3:
    x += .0001
    if x == 2.5:
        print "X is now: ", x
        break
    else:
        print x

当我在 PyCharm 中运行它时,我得到了这个输出(我已经缩短了它,所以你不必滚动浏览一堆数字。)

2.4988
2.4989
2.499
2.4991
2.4992
2.4993
2.4994
2.4995
2.4996
2.4997
2.4998
2.4999
2.5
2.5001
2.5002
2.5003
2.5004
2.5005
2.5006
2.5007
2.5008
2.5009
2.501

Pycharm 的行为就像我的“if”语句不存在一样。它直接跳过数字 2.5 而不运行

if x == 2.5:
    print "X is now: ", x
    break

我认为这与我的计算机运行这些数字的方式有关,而我看到的 2.5 实际上是 2.5000001 或其他东西,但我不知道。我尝试将这些数字放入科学记数法中,希望它会有所帮助,但我得到了错误“太多的输出无法处理”

我对 python 还很陌生,并且开始对此感到恼火。任何和所有帮助它表示赞赏。谢谢。

【问题讨论】:

  • 使用print(repr(x))查看浮点数的(几乎)准确值,并使用x =decimal.Decimal()防止这种情况发生

标签: python numbers decimal pycharm


【解决方案1】:

在处理浮点数学时,通常最好有一些 epsilon 值来比较数据以进行阈值比较。例如

if abs( x - 2.5 ) < 0.001
    print  "X is now ", x
    break;

【讨论】:

  • @TadhgMcDonald-Jensen 除了这是解决浮点不准确性的基本 ComSci 方法之外,我不太确定这是一个重复的答案。
  • 对不起,不是 duplicate 每句话,但是这个方法已经被建议用于这个问题是重复的问题。
  • @TadhgMcDonald-Jensen 啊,可以理解。老实说,我什至没有看重复的问题,因为这是一个相对简单的修复,我只是快速输入了一个答案来帮助解决 OP 的问题。这是比较浮点值的一种常见(即使不是最好的也很简单)的方法,我相信这个网站上可能有成百上千个几乎相同的答案。
  • 谢谢克里斯 :) 这解决了我的问题。另外,Tadhg,谢谢你的链接,我想我的谷歌搜索技能没有我想象的那么好。
【解决方案2】:

罪魁祸首是浮点数学。

浮点数学:

您的语言没有损坏,它正在做浮点数学运算。计算机本身只能存储整数,因此它们需要某种方式来表示十进制数。这种表示带有某种程度的不准确。这就是为什么,通常情况下,0.1 + .2 != .3。 为什么会这样?

其实很简单。当您有一个以 10 为底的系统(如我们的系统)时,它只能表示使用基数的质因子的分数。 10 的质因数是 2 和 5。所以 1/2、1/4、1/5、1/8 和 1/10 都可以清楚地表示,因为分母都使用 10 的质因数。相比之下,1 /3、1/6 和 1/7 都是重复小数,因为它们的分母使用 3 或 7 的质因数。在二进制(或以 2 为底)中,唯一的质因数是 2。所以你只能清楚地表达分数仅包含 2 作为主要因素。在二进制中,1/2、1/4、1/8 都可以清楚地表示为小数。而 1/5 或 1/10 将重复小数。所以 0.1 和 0.2(1/10 和 1/5)虽然在以 10 为底的系统中是干净的小数,但在计算机正在运行的以 2 为底的系统中重复小数。当你对这些重复的小数进行数学运算时,你最终会得到剩菜当您将计算机的以 2 为基数(二进制)的数字转换为更易于人类阅读的以 10 为基数的数字时,它会继续存在。

来源:http://0.30000000000000004.com/

【讨论】:

    【解决方案3】:

    正如其他人所指出的,问题在于浮点数学。对于小数字的精确表示,您可能需要查看 python 的decimal module

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-09-06
      • 1970-01-01
      • 2011-10-25
      • 1970-01-01
      • 1970-01-01
      • 2012-12-16
      • 2014-02-06
      相关资源
      最近更新 更多