分数(有理数)の計算

分数(有理数)の計算

分数(有理数)の計算

 除算演算子で割り算をすると誤差が生じることがあるので、データを 分数の形に保存したままで計算したい 場面があります。Python で分数計算を行なうためには、標準ライブラリの fractionsモジュールから Fractionクラス(有理数型) をインポートします (Sympy というモジュールを使う方法もありますが、それは別の記事で解説します)。

Fractionクラスのデータを定義します

 Fractionクラス(有理数型)に引数を与えて呼びだすと、Fractionインスタンス(オブジェクト)が生成されます。

 引数に 2 つの整数値を与えると、第 1 引数を分子、第 2 引数を分母とした有理数型データが定義されます。分母を省略すると 1 とみなされます。

# Fraction クラスを呼びだします
from fractions import Fraction

# Fractionインスタンスを生成します
a = Fraction(1,3)

# a の値を表示します
print(a)
1/3

 引数に小数型 (float) の値を渡して有理数型 (Fraction) に変換することもできます。

from fractions import Fraction

# 0.125 を分数に変換します
a = Fraction(0.125)

print(a)
1/8

 

分母と分子を取り出します

 引数に Fractionクラスの属性 Fraction.numerator もしくは Fraction.denominator を指定すると、分子と分母の値を取得することができます。

from fractions import Fraction

x = Fraction(19,33)

# 分子を取得します
a = x.numerator

# 分母を取得します
b = x.denominator

print(a, b)
19 33

 

分数同士の加減乗除

 分数同士の加減乗除を試してみます。

from fractions import Fraction

# 1/2 + 1/3
a = Fraction(1,2) + Fraction(1,3)

# 1/2 - 1/3
b = Fraction(1,2)-Fraction(1,3)

# (1/2)×(1/3)
c = Fraction(1,2)*Fraction(1,3)

# (1/2)÷(1/3)
d = Fraction(1,2)/Fraction(1,3)

print(a, b, c, d)
5/6 1/6 1/6 3/2

 

小数の近似分数を得ます

 Fractionクラスの limit_denominatorメソッドを使うと、指定した引数に最も近い分母をもつ近似分数を得ることができます。

 mathモジュールから円周率の値をインポートして、その近似分数を求めてみます。

# 円周率の値を呼びだします
from math import pi
from fractions import Fraction

# 円周率の値を分数に変換します
x = Fraction(pi)

# 円周率の近似分数を取得します
f_pi = x.limit_denominator(1000)

print(f_pi)
355/113

 ちなみに、この近似分数のことを「密率」とよびます。大昔の中国人が発見したそうです。
 密率は小数点以下 6 桁まで一致する精度がありますが、もう少し手軽に計算に使える「約率」も求めておきましょう。

# 円周率の値を呼びだします
from math import pi
from fractions import Fraction

# 円周率の値を分数に変換します
x = Fraction(pi)

# 円周率の近似分数を取得します
f_pi = x.limit_denominator(10)

print(f_pi)
22/7

 

級数を計算してみます

 最後に分数計算の応用です。次のような級数

  1 + 1/2 + 1/3 + 1/4 + 1/5 + 1/6 + ......

を 20 項まで計算してみます。

from fractions import Fraction

x = 0
m = 0

for ct in range(20):
    m += 1
    x += Fraction(1, m)

print(x)
55835135/15519504

 このサンプルコードでは、m の値を 1 つずつ増やしながら Fraction を作り、それを次々と足し合わせています。