Python无限 – 任何警告?
所以Python有正面和负面的无限性:
float("inf"), float("-inf")
这看起来像是需要警告的functiontypes。 有什么我应该知道的?
你仍然可以从涉及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
值被认为是一个非常特殊的值,具有不同寻常的语义,所以最好直接通过exception知道OverflowError
,而不是将inf
值静静地注入到你的计算中。
Python的实现很好地遵循IEEE-754标准 ,您可以使用它作为指导,但它依赖于编译的底层系统,因此可能会出现平台差异 。 最近¹,已经应用了一个允许“无穷大”以及“inf”的修复方法,但是这里没有什么重要的。
以下各节同样适用于正确实现IEEE浮点运算的任何语言,它并不仅限于Python。
不平等的比较
当处理无穷大和大于或小于<
运算符时,以下计数:
- 包括
+inf
任何数字都高于-inf
- 包括
-inf
任何数字都低于+inf
-
+inf
既不高于也不低于+inf
-
-inf
既不高于也不低于-inf
- 任何涉及
NaN
比较都是错误的(inf
既不高也不低于NaN
)
比较平等
比较平等时, +inf
和+inf
是相等的,就像-inf
和-inf
。 这是一个非常有争议的问题,可能听起来有争议,但它是在IEEE标准和Python的行为就像这样。
当然, +inf
不等于-inf
,包括NaN
在内的所有东西都不等于NaN
。
用无穷大计算
除非两个操作数都是无穷大的,否则大多数无穷大的计算都会产生无穷大的结果,当运算的分数或模数,或者乘以零时,有一些特殊的规则需要记住:
- 当乘以零,其结果是不确定的,它会产生
NaN
- 当除了无穷大以外的任何数字(无穷大本身除外),这会产生
0.0
或-0.0
。 - 当用正或负无穷分(包括模)正或负无穷时,结果是不确定的,所以
NaN
。 - 当减去时,结果可能会令人惊讶,但遵循常见的math意义 :
- 当做
inf - inf
,结果是undefined:NaN
; - 当
inf - -inf
,结果是inf
; - 当执行
-inf - inf
,结果是-inf
; - 当执行
-inf - -inf
,结果是undefined:NaN
。
- 当做
- 添加时,也可能同样令人惊讶:
- 当
inf + inf
,结果是inf
; - 在做
inf + -inf
,结果是undefined:NaN
; - 当执行
-inf + inf
,结果是undefined:NaN
; - 当执行
-inf + -inf
,结果是-inf
。
- 当
- 使用
math.pow
,pow
或**
是棘手的,因为它不像它应该那样。 当两个实数的结果太高而不适合双精度浮点数(它应该返回无穷大)时,它会抛出一个溢出exception,但是当input是inf
或-inf
,它的行为是正确的,并返回inf
或0.0
。 当第二个参数是NaN
,它将返回NaN
,除非第一个参数是1.0
。 还有更多的问题,并非全部在文档中涵盖 。 -
math.exp
遇到与math.exp
相同的问题。 解决这个溢出的解决scheme是使用类似于这样的代码:try: res = math.exp(420000) except OverflowError: res = float('inf')
笔记
注1:作为IEEE标准定义的附加警告,如果计算结果不足或溢出,结果将不是溢出或溢出错误,而是正或负的无穷大: 1e308 * 10.0
产生inf
。
注意2:因为用NaN
任何计算都返回NaN
并且与NaN
任何比较,包括NaN
本身都是false
,所以应该使用math.isnan
函数来确定一个数字是否确实是NaN
。
注3:尽pipePython支持写入float('-NaN')
,但是符号被忽略,因为NaN
内部没有任何符号。 如果你除-inf / +inf
,结果是NaN
,而不是-NaN
(没有这样的事情)。
注意4:要小心依赖上面的任何一个,因为Python依赖于编译的C或Java库,并不是所有的底层系统都能正确实现所有这些行为。 如果你想确定,在做计算之前testing无穷大。
¹)最近意味着从版本3.2 。
²)浮点支持正数和负数零,所以: x / float('inf')
保持其符号, -1 / float('inf')
产生1 / float(-inf)
产生1 / float(-inf)
1 / float('inf')
产生0.0
, -1/ float(-inf)
产生0.0
。 另外, 0.0 == -0.0
是true
,如果你不希望它是true
,你必须手动检查这个符号。
C99也是如此 。
所有现代处理器所使用的IEEE 754浮点表示都具有为正无穷(sign = 0,exp =〜0,frac = 0),负无穷(sign = 1,exp =〜0,frac = 0) )和许多NaN(不是数字:exp =〜0,frac≠0)。
所有你需要担心的是:一些算术可能会导致浮点exception/陷阱,但不仅限于这些“有趣”的常量。