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/陷阱,但不仅限于这些“有趣”的常量。