Python无限-有什么需要注意的吗?

2024-05-08 18:10:22 发布

您现在位置:Python中文网/ 问答频道 /正文

所以Python有正负无穷大:

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

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


Tags: 功能floatinf
3条回答

C99也是。

所有现代处理器使用的IEEE 754浮点表示法都有几个特殊的位模式,保留给正无穷大(sign=0,exp=~0,frac=0)、负无穷大(sign=1,exp=~0,frac=0)和许多NaN(不是数字:exp=~0,frac不等于0)。

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

您仍然可以从涉及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值。

Python's implementation很好地遵循了IEEE-754 standard,您可以将其用作指导,但它依赖于编译它所依赖的底层系统,因此platform differences可能会发生。最近,已经应用了一个允许"infinity" as well as "inf"的修复程序,但这在这里并不重要。

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

不等式的比较

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

  • 包括+inf在内的任何数字都高于-inf
  • 包括-inf在内的任何数字都低于+inf
  • +infneither higher nor lower而不是+inf
  • -inf既不高于也不低于-inf
  • 任何涉及NaN的比较都是错误的(inf既不高于也不低于NaN

相等性比较

当比较相等时,+inf+inf是相等的,同样的还有-inf-inf。这是一个很有争议的问题,听起来可能会有争议,但在IEEE标准中,Python的行为就是这样。

当然,+inf不等于-inf,所有东西,包括NaN本身,都不等于NaN

无穷大

的计算

除非两个操作数都是无穷大,否则大多数具有无穷大的计算都会产生无穷大,当运算除法或模运算或与零相乘时,需要记住一些特殊的规则:

  • 当乘以0(结果未定义)时,它产生NaN
  • 当把任何数字(除了无穷大本身)除以无穷大时,会产生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.expmath.pow有相同的问题。解决此溢出问题的方法是使用类似于以下代码:

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

注释

注1:作为另一个警告,根据IEEE标准的定义,如果计算结果不足或溢出,结果将不是不足或溢出错误,而是正或负无穷大:1e308 * 10.0产生inf

注2:因为任何带有NaN的计算都返回NaN,并且任何与NaN的比较,包括NaN本身就是false,所以应该使用^{}函数来确定一个数字是否确实是NaN

注意3:虽然Python支持写float('-NaN'),但是忽略符号,因为内部不存在NaN上的符号。如果除以-inf / +inf,结果是NaN,而不是-NaN(没有这样的东西)。

注4:注意在上面,由于Python依赖于它所编译的C或Java库,所以并不是所有的底层系统都能正确地实现所有这些行为。如果你想确定,在计算之前先测试无穷大。

(1)最近指version 3.2.
(2)浮点支持正零和负零,因此:x / float('inf')保留其符号,-1 / float('inf')产生-0.01 / float(-inf)产生-0.0,^{{产生0.0-1/ float(-inf)产生^}。此外,^{} is ^{},如果不想让符号为真,则必须手动检查该符号。

相关问题 更多 >