無窮大和 NaN(不是數字)

在所有版本的 Python 中,我們可以表示無限和 NaN(非數字),如下所示:

pos_inf = float('inf')     # positive infinity
neg_inf = float('-inf')    # negative infinity
not_a_num = float('nan')   # NaN ("not a number")

在 Python 3.5 及更高版本中,我們還可以使用定義的常量 math.infmath.nan

Python 3.x >= 3.5

pos_inf = math.inf
neg_inf = -math.inf
not_a_num = math.nan

字串表示顯示為 inf-infnan

pos_inf, neg_inf, not_a_num
# Out: (inf, -inf, nan)

我們可以使用 isinf 方法測試正或負無窮大:

math.isinf(pos_inf)
# Out: True

math.isinf(neg_inf)
# Out: True

我們可以通過直接比較專門測試正無窮大或負無窮大:

pos_inf == float('inf')    # or  == math.inf in Python 3.5+
# Out: True

neg_inf == float('-inf')   # or  == -math.inf in Python 3.5+
# Out: True

neg_inf == pos_inf
# Out: False

Python 3.2 及更高版本還允許檢查有限性:

Python 3.x >= 3.2

math.isfinite(pos_inf)
# Out: False

math.isfinite(0.0)
# Out: True

比較運算子按正常和負無窮大的預期工作:

import sys

sys.float_info.max
# Out: 1.7976931348623157e+308  (this is system-dependent)

pos_inf > sys.float_info.max
# Out: True

neg_inf < -sys.float_info.max
# Out: True

但是如果算術表示式產生的值大於可以表示為 float 的最大值,它將變為無窮大:

pos_inf == sys.float_info.max * 1.0000001
# Out: True

neg_inf == -sys.float_info.max * 1.0000001
# Out: True

然而,除以零不會給出無窮大的結果(或者在適當的情況下給出負無窮大),而是提出了一個 ZeroDivisionError 異常。

try:
    x = 1.0 / 0.0
    print(x)
except ZeroDivisionError:
    print("Division by zero")

# Out: Division by zero

無窮大的算術運算只能給出無限的結果,有時甚至是 NaN:

-5.0 * pos_inf == neg_inf
# Out: True

-5.0 * neg_inf == pos_inf
# Out: True

pos_inf * neg_inf == neg_inf
# Out: True

0.0 * pos_inf
# Out: nan

0.0 * neg_inf
# Out: nan

pos_inf / pos_inf
# Out: nan

NaN 永遠不等於任何東西,甚至不是自己。我們可以用 isnan 方法測試它:

not_a_num == not_a_num
# Out: False

math.isnan(not_a_num)
Out: True

NaN 總是比較為不相等,但絕不會小於或大於:

not_a_num != 5.0   # or any random value
# Out: True

not_a_num > 5.0   or   not_a_num < 5.0   or   not_a_num == 5.0
# Out: False

對 NaN 的算術運算總是給出 NaN。這包括乘以 -1:沒有“負 NaN”。

5.0 * not_a_num
# Out: nan

float('-nan')
# Out: nan

Python 3.x >= 3.5

-math.nan
# Out: nan

舊的 float 版 NaN 和 infinity 與 Python 3.5+ math 庫常量之間有一個細微的區別:

Python 3.x >= 3.5

math.inf is math.inf, math.nan is math.nan
# Out: (True, True)

float('inf') is float('inf'), float('nan') is float('nan')
# Out: (False, False)