べき乗演算

べき乗演算

べき乗の演算

 Python で べき乗(冪乗) を計算させるには、次のような方法があります。

 ① 算術演算子「 ** 」を使う。
 ② 組み込みの pow関数を使う。
 ③ mathモジュールの pow関数をインポートする。

 それぞれの機能が微妙に異なっているので、実例(サンプルコード)を使いながら順に解説していきます。

算術演算子によるべき乗演算

 算術演算子「 ** 」を用いて 「 x の y 乗」を計算するときは次のように記述します。

 x ** y

 x は底、y は指数です。いずれもべき演算が定められている範囲において、整数、浮動小数点数、複素数を指定することができます。

# 算術演算子によるべき乗演算
a = 10 ** 2
b = 10 ** 1.5
c = 10 ** -2
d = 10.0 ** 3
e = (2 + 3j) ** 3

print("a =", a)
print("b =", b)
print("c =", c)
print("d =", d)
print("e =", e)
a = 100
b = 31.622776601683793
c = 0.01
d = 1000.0
e = (-46+9j)

 数学においては、0 の 0 乗は分野によって定義・未定義が分かれるところですが、Python では $0^0 = 1$ と定義されています。

# 0の0乗
a = 0 ** 0
b = 0.0 ** 0.0
c = 0j ** 0j

print("a =", a)
print("b =", b)
print("c =", c)
a = 1
b = 1.0
c = (1+0j)

 これは解析学の研究などで Python を活用するときに、本来なら未定義であるはずの値が出力されてしまうという危険性を孕んでいます。$0^0$ が定義されない分野においては、ループ処理などで変数に $0^0$ の演算結果が入り込まないように細心の注意を払う必要があります。
 

組み込み関数 pow によるべき乗演算

 Python にビルト・インされている(組込まれている)pow関数 は次のような記法で呼びだします。

 pow(x, y [,z])

 引数の指定が 2 つであれば、算術演算子 ** と同じはたらきをします。

# pow関数によるべき乗演算
a = pow(10, 2)
b = pow(10, 1.5)
c = pow(10, -2)
d = pow(10.0, 3)
e = pow(2 + 3j, 3)

print("a =", a)
print("b =", b)
print("c =", c)
print("d =", d)
print("e =", e)
a = 100
b = 31.622776601683793
c = 0.01
d = 1000.0
e = (-46+9j)

 オプション引数 z を指定すると、x の y 乗を z で割ったときの剰余(余り)を返します。

# 10の2乗を7で割った余り
a = pow(10, 2, 7)

print(a)
2

 pow(x, y, z) は pow(x, y) % z よりも高速で処理できるように設計されています。べき乗の剰余というのは、数論の分野で多用される演算です。興味のあるかたは 整数論入門講座 の各記事を参照してください。
 

math.pow によるべき乗演算

 標準ライブラリの mathモジュールをインポートすると、math.pow関数 が使えるようになります。

 math.pow(x, y)

 算術演算子「 ** 」や組み込みの pow関数とは異なり、math.pow関数は与えられた 2 つの引数の型が何であっても、浮動小数点数型に変換して演算します。もちろん戻り値も浮動小数点数となります。複素数型は浮動小数点数型に変換できないので、math.pow では引数に複素数を指定するとエラーを返します。

import math

# math.pow関数によるべき乗演算
a = math.pow(10, 2)
b = math.pow(10, 1.5)
c = math.pow(10, -2)
d = math.pow(10.0, 3)
e = math.pow(0, 0)

print("a =", a)
print("b =", b)
print("c =", c)
print("d =", d)
print("e =", e)
a = 100.0
b = 31.622776601683793
c = 0.01
d = 1000.0
e = 1.0

 math.pow関数は底 x に負数、指数 y に整数以外の数値を指定するとエラーを返します。ただし、y が浮動小数点数型であっても、1.0 や 2.0 のように値が整数であれば問題ありません。

# mathモジュールのインポート
import math

# math.pow関数によるべき乗演算
a = math.pow(-2, 3.0)

print(a)
-8.0

 このように、math.pow関数は算術演算子「 ** 」や組み込みの pow関数に比べると演算機能が限定されていますが、これは実数範囲での指数演算の規則に合致するものです。これは通常の計算においては、おかしな値が入れられたときにエラーを返して警告してくれる math.pow関数のほうが利用しやすいことを意味します。「負数の非整数乗」のような演算は用途が限られています。これについては、以下で簡単に補足しておきます。
 

複素解析学の領域です

 算術演算子「 ** 」もしくは組み込みの pow関数を使うと、「-10 の 0.2 乗」や「 2 の i 乗」といった演算をさせても値を返してきます。

a = (-10) ** 0.2
b = 2 ** 1j

print("a =", a)
print("b =", b)
a = (1.282205526970205+0.931576844987379j)
b = (0.7692389013639721+0.6389612763136348j)

 この演算の意味を理解するには「複素解析学」という高度な専門知識が必要となります。ある分野の研究には、こうした演算も必要となるかもしれません。しかし、あくまで実数範囲で指数計算を行なう場合は、この機能はかえって危険なものとなりえます。実数範囲で定義されないはずの仕方で引数が指定されたとしても、例外処理がなされずに値を返してくるからです。上のサンプルコードにあるように「-10 の 0.2 乗」は引数がともに実数なので、いかにも「ありそうな演算」に思えて見過ごしてしまうかもしれません(演算結果は複素数になっています!)。あからさまにこうした式を書くことがなくても、ループ処理の最中に変数にこうした演算結果が紛れ込む可能性もあります。ですから実数範囲でベキ演算を安全に行うために、敢えて演算機能を制限した math.pow関数が用意されているのです。