ゼロで割ることはできません。無理に割ろうとすると
1 / 0
ZeroDivisionError というエラーになります。
しかし、コンピュータによる数値計算では、a / b
のような割り算のときに、たまにしか起こらないエラーのためにいちいち b
がゼロかどうか確認するのは面倒ですし、速度的にも不利です。
そこで、浮動小数点演算の IEEE 754 という規格では、1.0 / 0.0
に相当する「無限大」という数や、0.0 / 0.0
に相当する「非数」という数を導入して、割り算がエラーにならない仕組みを用意しています。
この仕組みをどう使うかは、言語によって異なります。
R では、1 / 0
と打ち込むと Inf
(Infinity = 無限大)と返ってきます。0 / 0
は NaN
(Not a Number = 非数)になります。いずれにしても、エラーで止まることはありません。
Ruby では、1 / 0
や 0 / 0
は ZeroDivisionError になって止まりますが 1.0 / 0.0
は Infinity
、0.0 / 0.0
は NaN
になります。C言語でも同じです。
ところが Python では 0
で割っても 0.0
で割っても ZeroDivisionError になり、そこで実行が止まってしまいます。これでは不便です。もちろん
try: x = a / b except ZeroDivisionError: if a == 0: x = float("nan") else: x = float("inf")
のようなことはできますが、面倒です。
Python でゼロで割って止まらないようにするには、NumPy を使います:
import numpy as np a = np.array([1.0, 0.0, -0.0]) print(a[0] / a[1]) print(a[1] / a[1]) print(a[0] / a[2])
inf nan -inf
ただし、RuntimeWarning(実行時の警告)が出ます。RuntimeWarning を出したくなければ、あらかじめ
np.seterr(divide="ignore", invalid="ignore")
と打ち込んでおきます(invalid とは 0/0 のこと)。元に戻すには
np.seterr(divide="warn", invalid="warn")
とします。デフォルトは
np.seterr(divide="warn", over="warn", under="ignore", invalid="warn")
で、ゼロ除算・オーバーフロー・0/0 が警告、アンダーフローが無視です。
特定の割り算だけ warn しないようにするには
with np.errstate(divide="ignore", invalid="ignore"): x = a[0] / a[1]
のようにします。
似た問題に「0の0乗」があります。Wikipediaの Zero to the power of zero で解説されているように、多くの処理系で1になります。Pythonも 0 ** 0
は1、0.0 ** 0.0
は1.0です。