所以Python有正负无限:
float("inf"), float("-inf")
这似乎只是需要注意的功能类型。有什么我应该知道的吗?
答案 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
。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.pow
,pow
或**
非常棘手,因为它的行为不应该如此。当具有两个实数的结果太高而不适合双精度浮点数(它应该返回无穷大)时,它会抛出溢出异常,但是当输入为inf
或-inf
时,它会正常运行并返回inf
或0.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
所以要小心!