Python无限 - 任何警告?

时间:2009-10-27 00:12:06

标签: python infinity

所以Python有正负无限:

float("inf"), float("-inf")

这似乎只是需要注意的功能类型。有什么我应该知道的吗?

5 个答案:

答案 0 :(得分:97)

Python's implementation非常好地跟随IEEE-754 standard,您可以将其用作指导,但它依赖于编译它的底层系统,因此可能会出现platform differences。最近¹,已经应用了一个允许"infinity" as well as "inf"的修复,但这在这里不太重要。

以下各节同样适用于任何正确实现IEEE浮点运算的语言,它不仅仅适用于Python。

不平等的比较

在处理无穷大且大于>或小于<运算符时,以下计数:

  • 包括+inf在内的任何数字都高于-inf
  • 包括-inf在内的任何数字都低于+inf
  • +inf neither higher nor lower+inf
  • -inf既不高于也不低于-inf
  • 涉及NaN的任何比较均为false(inf既不高于,也不低于NaN

平等比较

比较相等时,+inf+inf相同,-inf-inf也是如此。这是一个备受争议的问题,可能听起来有争议,但它符合IEEE标准,Python的行为就像那样。

当然,+inf不等于-inf,包括NaN本身在内的所有内容都不等于NaN

使用无穷大计算

大多数使用无穷大的计算都会产生无穷大,除非两个操作数都是无穷大,当操作除法或模数,或者乘以零时,需要记住一些特殊规则:

  • 当乘以零时,结果未定义,则产生NaN
  • 将任意数字(无穷大本身除外)除以无穷大,产生0.0-0.0²。
  • 将正或负无穷大除以(包括模)阳性或负无穷大时,结果未定义,因此NaN
  • 减去时,结果可能会令人惊讶,但请遵循common math sense
    • 在执行inf - inf时,结果未定义:NaN;
    • 执行inf - -inf时,结果为inf;
    • 执行-inf - inf时,结果为-inf;
    • 执行-inf - -inf时,结果未定义:NaN
  • 添加时,也同样令人惊讶:
    • 执行inf + inf时,结果为inf;
    • 在执行inf + -inf时,结果未定义:NaN;
    • 在执行-inf + inf时,结果未定义:NaN;
    • 执行-inf + -inf时,结果为-inf
  • 使用math.powpow**非常棘手,因为它的行为不应该如此。当具有两个实数的结果太高而不适合双精度浮点数(它应该返回无穷大)时,它会抛出溢出异常,但是当输入为inf-inf时,它会正常运行并返回inf0.0。当第二个参数为NaN时,它将返回NaN,除非第一个参数为1.0。还有更多问题,而不是全部covered in the docs
  • math.exp遇到与math.pow相同的问题。解决溢出问题的解决方案是使用与此类似的代码:

    try:
        res = math.exp(420000)
    except OverflowError:
        res = float('inf')
    

注释

注1:作为附加警告,如IEEE标准所定义,如果您的计算结果不足或溢出,结果将不会出现欠错或溢出错误,但是为正或者负无穷大:1e308 * 10.0产生inf

注意2:因为NaN的所有计算都返回NaN,与NaN的任何比较都包括NaN本身{{1} },您应该使用math.isnan函数来确定某个数字是否确实false

注3:虽然Python支持编写NaN,但会忽略该符号,因为内部float('-NaN')上没有符号。如果您划分NaN,结果为-inf / +inf,而不是NaN(没有这样的事情)。

注4:要小心依赖上述任何一项,因为Python依赖于它编译的C或Java库,并非所有底层系统都能正确实现所有这些行为。如果你想确定,在进行计算之前测试无穷大。

¹)最近意味着自version 3.2以来 ²)浮点支持正零和负零,因此:-NaN保持其符号,x / float('inf')收益-1 / float('inf')-0.0收益1 / float(-inf)-0.0收益率1 / float('inf')0.0收益率-1/ float(-inf)。另外,0.0 == -0.0 is true,如果你不想让它成为真,你必须手动检查标志。

答案 1 :(得分:95)

您仍然可以从涉及inf的简单算术中获取非数字(NaN)值:

>>> 0 * float("inf")
nan

请注意,您通常 通过常规算术计算获得inf值:

>>> 2.0**2
4.0
>>> _**2
16.0
>>> _**2
256.0
>>> _**2
65536.0
>>> _**2
4294967296.0
>>> _**2
1.8446744073709552e+19
>>> _**2
3.4028236692093846e+38
>>> _**2
1.157920892373162e+77
>>> _**2
1.3407807929942597e+154
>>> _**2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
OverflowError: (34, 'Numerical result out of range')

inf值被认为是具有异常语义的非常特殊的值,因此最好直接通过异常了解OverflowError,而不是静默注入inf值进入你的计算。

答案 2 :(得分:3)

C99也是如此。

所有现代处理器使用的IEEE 754浮点表示具有为正无穷大保留的几种特殊位模式(符号= 0,exp =〜0,frac = 0),负无穷大(符号= 1,exp = ~0, frac = 0),和许多NaN(非数字:exp =〜0,frac≠0)。

您需要担心的是:某些算术可能会导致浮点异常/陷阱,但这些并不仅限于这些“有趣”的常量。

答案 3 :(得分:2)

我发现了一个警告,到目前为止还没有人提到过。我不知道它是否会在实际情况下出现,但这里是为了完整。

通常,计算模数无穷大的数字会将其自身返回为浮点数,但模数无穷大的分数会返回nan(不是数字)。这是一个例子:

>>> from fractions import Fraction
>>> from math import inf
>>> 3 % inf
3.0
>>> 3.5 % inf
3.5
>>> Fraction('1/3') % inf
nan

我在Python bug跟踪器上提出了一个问题。它可以在https://bugs.python.org/issue32968看到。

更新:这将是fixed in Python 3.8

答案 4 :(得分:2)

  

非常糟糕的警告:被零除

1/x的分数表示,直到x = 1e-323为止是inf,但是当x = 1e-324或更少时,它抛出ZeroDivisionError

>>> 1/1e-323
inf

>>> 1/1e-324
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ZeroDivisionError: float division by zero

所以要小心!