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.powpow**是棘手的,因为它不像它应该那样。 当两个实数的结果太高而不适合双精度浮点数(它应该返回无穷大)时,它会抛出一个溢出exception,但是当input是inf-inf ,它的行为是正确的,并返回inf0.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.0true ,如果你不希望它是true ,你必须手动检查这个符号。

C99也是如此 。

所有现代处理器所使用的IEEE 754浮点表示都具有为正无穷(sign = 0,exp =〜0,frac = 0),负无穷(sign = 1,exp =〜0,frac = 0) )和许多NaN(不是数字:exp =〜0,frac≠0)。

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