所以Python有正无穷和负无穷:

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

这似乎是必须有一些警告的功能类型。有什么我应该注意的吗?

有帮助吗?

解决方案

您仍然可以从涉及 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的实现 遵循 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.
  • 相减时,结果可能会令人惊讶,但遵循 数学常识:
    • 当做 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. 。还有更多问题,不是全部 文档中涵盖.
  • 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 本身就是 false, ,你应该使用 math.isnan 判断一个数字是否确实的函数 NaN.

注3: 虽然Python支持写 float('-NaN'), ,该符号被忽略,因为不存在任何符号 NaN 内部。如果你分 -inf / +inf, ,结果是 NaN, , 不是 -NaN (哪有这回事)。

注4: 请小心依赖上述任何一项,因为 Python 依赖于为其编译的 C 或 Java 库,并且并非所有底层系统都正确实现所有这些行为。如果您想确定,请在计算之前测试无穷大。

1) 最近是指自 3.2版本.
²) 浮点数支持正零和负零,因此: 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 == -0.0true, ,如果您不希望该符号为真,则必须手动检查该符号。

C99 也是如此。

所有现代处理器使用的IEEE 754浮点表示具有为正无穷大保留的几种特殊位模式(符号= 0,exp =〜0,frac = 0),负无穷大(符号= 1,exp = ~0, frac = 0),和许多NaN(非数字:exp =〜0,frac≠0)。

您需要担心的是:某些算术可能会导致浮点异常/陷阱,但这些并不仅限于这些“有趣”的异常/陷阱。常数。

我发现了一个警告,到目前为止还没有人提到过。我不知道它是否会在实际情况下经常出现,但这是为了完整起见。

通常,计算模数无穷大的数字会将其自身返回为浮点数,但模数无穷大的分数将返回 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 上看到。

更新:这将是在Python 3.8中修复

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top