Pythonで無限大を表すinfの作成・演算・判定・比較

Modified: | Tags: Python, 数値

Pythonの浮動小数点数float型には無限大を表すinfがある。infの作成方法およびinfを含む演算、判定、比較について説明する。

浮動小数点数float型の無限大inf

Pythonでは浮動小数点数float型に無限大を表すinfがある。

コンストラクタfloat()の引数に文字列'inf'を指定すると生成できる。その他の生成方法については後述。

f_inf = float('inf')

print(f_inf)
# inf

print(type(f_inf))
# <class 'float'>
source: inf_float.py

負の無限大

無限大inf-をつけると負の無限大を表せる。

f_inf_minus = -float('inf')

print(f_inf_minus)
# -inf

print(type(f_inf_minus))
# <class 'float'>
source: inf_float.py

他の型への変換

通常のfloat型の値はint()で整数int型に変換できるが、infは変換できない。

f_inf = float('inf')

# print(int(f_inf))
# OverflowError: cannot convert float infinity to integer
source: inf_float.py

文字列str型にはstr()で変換可能。'inf'という文字列に変換される。

print(str(f_inf))
# inf

print(type(str(f_inf)))
# <class 'str'>
source: inf_float.py

無限大infの作成

infを作成する方法はいくつかある。

float()で作成

コンストラクタfloat()に文字列'inf'または'infinity'を指定するとinfが作成できる。小文字と大文字の区別はなく、小文字と大文字が混ざっていても問題ない。

print(float('inf'))
# inf

print(float('infinity'))
# inf

print(float('INF'))
# inf

print(float('INFinity'))
# inf
source: inf_float.py

float型の最大値を超える浮動小数点数

float型が取り得る最大値を超える浮動小数点数は自動的にinfとして扱われる。

import sys

f_inf_num = sys.float_info.max * 2

print(f_inf_num)
# inf
source: inf_float.py

sys.float_info.maxfloat型の最大値を取得している。詳細は以下の記事を参照。

標準ライブラリのmathモジュール: math.inf

標準ライブラリのmathモジュールをインポートするとmath.infinfを作成可能。特別な型ではなくfloat型。

import math

print(math.inf)
# inf

print(type(math.inf))
# <class 'float'>

print(float('inf') == math.inf)
# True
source: inf_math.py

NumPy: np.inf

mathモジュールと同じく、サードパーティライブラリのNumPyでもinfを作成可能。こちらも特別な型ではなくfloat型。

import numpy as np

print(np.inf)
# inf

print(type(np.inf))
# <class 'float'>

print(float('inf') == np.inf)
# True
source: inf_numpy.py

無限大infを含む演算

無限大infに対しても四則演算(足し算、引き算、掛け算、割り算)およびべき乗が可能。

無限大infには何を足しても無限大inf

print(float('inf') + 100)
# inf

print(float('inf') + float('inf'))
# inf
source: inf_calc.py

無限大infから無限大infを引くとnanとなる。nanNot a Numberの略で非数を表す。nanfloat型の値。

それ以外の値を引いても無限大infのまま。

print(float('inf') - 100)
# inf

print(float('inf') - float('inf'))
# nan

print(type(float('inf') - float('inf')))
# <class 'float'>
source: inf_calc.py

無限大infに0を掛けるとnan。それ以外は無限大inf

print(float('inf') * 2)
# inf

print(float('inf') * float('inf'))
# inf

print(float('inf') * 0)
# nan
source: inf_calc.py

無限大infを無限大infで割るとnan0を無限大infで割ると00で割るとエラー。それ以外は無限大inf

print(float('inf') / 2)
# inf

print(float('inf') / float('inf'))
# nan

print(0 / float('inf'))
# 0.0

# print(float('inf') / 0)
# ZeroDivisionError: float division by zero
source: inf_calc.py

べき乗

無限大inf0乗は11の無限大inf乗は10の無限大inf乗は0。それ以外は無限大inf

print(float('inf') ** 2)
# inf

print(float('inf') ** float('inf'))
# inf

print(float('inf') ** 0)
# 1.0

print(2 ** float('inf'))
# inf

print(1 ** float('inf'))
# 1.0

print(0 ** float('inf'))
# 0.0
source: inf_calc.py

無限大infの判定: ==, math.isinf(), np.isinf()

float型の最大値を超える値(=無限大)と範囲内の値(≠無限大)を例とする。eXXX10XXX乗の意味。

print(1e1000)
# inf

print(1e100)
# 1e+100

==演算子

ある値が無限大infであるかどうかは==で判定可能。

print(1e1000 == float('inf'))
# True

print(1e100 == float('inf'))
# False

無限大infを作成する方法はいくつかあるが、すべて同じfloat型の値なので、どれを使っても問題ない。

import math
import numpy as np

print(float('inf') == math.inf == np.inf)
# True

print(1e1000 == math.inf)
# True

print(1e100 == math.inf)
# False

また、上述のように、無限大infの演算結果の多くは無限大infとなるため、以下のような式もTrueとなる。

print(float('inf') == float('inf') * 100)
# True

math.isinf()

mathモジュールには関数math.isinf()が用意されている。

math.isinf()は負の無限大に対してもTrueを返す。

import math

print(math.isinf(1e1000))
# True

print(math.isinf(1e100))
# False

print(math.isinf(-1e1000))
# True

np.isinf(), np.isposinf(), np.isneginf(), np.isfinite()

NumPyにはmathと同様のnp.isinf()のほか、np.isposinf(), np.isneginf(), np.isfinite()がある。

np.isinf()は正負の無限大、np.isposinf()は正の無限大、np.isneginf()は負の無限大、np.isfinite()は有限の値(無限大ではない値)に対してTrueを返す。

いずれの関数も引数にNumPy配列ndarrayやリストなどのarray-likeオブジェクトを指定可能。True, Falseを要素とするndarrayが返される。

import numpy as np

a = np.array([1, np.inf, -np.inf])
print(a)
# [  1.  inf -inf]

print(np.isinf(a))
# [False  True  True]

print(np.isposinf(a))
# [False  True False]

print(np.isneginf(a))
# [False False  True]

print(np.isfinite(a))
# [ True False False]

スカラー値をそのまま指定することもできる。

print(np.isinf(1e1000))
# True

無限大を任意の値に置換する関数np.nan_to_num()も提供されている。

デフォルトでは表現可能な最大の値に置換される。NumPy1.17以降は引数posinf, neginfに正負の無限大を置換する値をそれぞれ指定可能。

print(np.nan_to_num(a))
# [ 1.00000000e+000  1.79769313e+308 -1.79769313e+308]

print(np.nan_to_num(a, posinf=1e100, neginf=-1e100))
# [ 1.e+000  1.e+100 -1.e+100]

デフォルトでは新たなndarrayが生成されるが、第二引数copyFalseとすると元のndarrayが変更される。

np.nan_to_num(a, copy=False)
print(a)
# [ 1.00000000e+000  1.79769313e+308 -1.79769313e+308]

なお、np.nan_to_num()はその名前の通り欠損値nanも置換する。詳細は以下の記事を参照。

無限大infの比較

比較演算子(>, <など)で無限大infを他の値と比較できる。

無限大inffloatおよびintの値と比較可能で、nanを除くどの値よりも大きい(nanとの比較はすべてFalse)。

以下に具体例を示す。

浮動小数点数floatとの比較

float型が取り得る最大値を例とする。

無限大inffloat型が取り得る最大値よりも大きく、負の無限大はfloat型が取り得る最小値よりも小さい。

import sys

print(sys.float_info.max)
# 1.7976931348623157e+308

print(float('inf') > sys.float_info.max)
# True

print(-float('inf') < -sys.float_info.max)
# True

nanとの比較

float型の特殊な値である非数nanの場合。nanfloat('nan')で生成できる。

print(float('nan'))
# nan

print(type(float('nan')))
# <class 'float'>

nanとの比較はすべての場合でFalseとなる。

print(float('inf') > float('nan'))
# False

print(float('inf') < float('nan'))
# False

print(float('inf') == float('nan'))
# False

整数intとの比較

整数int型との比較も可能。

print(float('inf') > 100)
# True

Python3では整数intの上限がないため、floatの最大値を超える値を格納することも可能だが、無限大infはそのような値よりも大きい。

import sys

large_int = int(sys.float_info.max) * 10

print(large_int)
# 1797693134862315708145274237317043567980705675258449965989174768031572607800285387605895586327668781715404589535143824642343213268894641827684675467035375169860499105765512820762454900903893289440758685084551339423045832369032229481658085593321233482747978262041447231687381771809192998812504040261841248583680

print(type(large_int))
# <class 'int'>

print(large_int > sys.float_info.max)
# True

print(float('inf') > large_int)
# True

なお、floatの最大値以下の整数intの値はfloat()floatに変換できるが、floatの最大値を超える整数intの値は変換できないので注意。

print(float(10**308))
# 1e+308

# print(float(10**309))
# OverflowError: int too large to convert to float

関連カテゴリー

関連記事