fractions – 有理数¶
目的: | 有理数を扱うクラスを提供する |
---|---|
利用できるバージョン: | 2.6 以上 |
Fraction クラスは、 numbers モジュールの Rational クラスで定義されている API に基づいた有理数の計算を実装します。
Fraction インスタンスを作成する¶
decimal と同様に、複数の方法で新たな値が作成されます。簡単な方法の1つは、別々に与えた分子と分母の値から作成することです。
import fractions
for n, d in [ (1, 2), (2, 4), (3, 6) ]:
f = fractions.Fraction(n, d)
print '%s/%s = %s' % (n, d, f)
新たな値として最小の共通分母を保持して計算されます。
$ python fractions_create_integers.py
1/2 = 1/2
2/4 = 1/2
3/6 = 1/2
別の方法としては、 <分子> / <分母> の文字列表現で Fraction インスタンスを作成します。
import fractions
for s in [ '1/2', '2/4', '3/6' ]:
f = fractions.Fraction(s)
print '%s = %s' % (s, f)
$ python fractions_create_strings.py
1/2 = 1/2
2/4 = 1/2
3/6 = 1/2
さらに、より一般的な10進数表現、または [<digits>].[<digits>] の浮動小数点表現を使用することもできます。
import fractions
for s in [ '0.5', '1.5', '2.0' ]:
f = fractions.Fraction(s)
print '%s = %s' % (s, f)
$ python fractions_create_strings_floats.py
0.5 = 1/2
1.5 = 3/2
2.0 = 2
float 型または decimal で表される有理数から直接、Fraction インスタンスを作成するクラスメソッドがあります。
import fractions
for v in [ 0.1, 0.5, 1.5, 2.0 ]:
print '%s = %s' % (v, fractions.Fraction.from_float(v))
有理数では正確に表せない浮動小数の値は予想外の結果を算出する可能性があることに注意してください。
$ python fractions_from_float.py
0.1 = 3602879701896397/36028797018963968
0.5 = 1/2
1.5 = 3/2
2.0 = 2
decimal で表した値を使用すると期待通りの結果になります。
import decimal
import fractions
for v in [ decimal.Decimal('0.1'),
decimal.Decimal('0.5'),
decimal.Decimal('1.5'),
decimal.Decimal('2.0'),
]:
print '%s = %s' % (v, fractions.Fraction.from_decimal(v))
$ python fractions_from_decimal.py
0.1 = 1/10
0.5 = 1/2
1.5 = 3/2
2.0 = 2
計算¶
Fraction をインスタンス化すると、期待した通りに数学の式で使用できます。
import fractions
f1 = fractions.Fraction(1, 2)
f2 = fractions.Fraction(3, 4)
print '%s + %s = %s' % (f1, f2, f1 + f2)
print '%s - %s = %s' % (f1, f2, f1 - f2)
print '%s * %s = %s' % (f1, f2, f1 * f2)
print '%s / %s = %s' % (f1, f2, f1 / f2)
$ python fractions_arithmetic.py
1/2 + 3/4 = 5/4
1/2 - 3/4 = -1/4
1/2 * 3/4 = 3/8
1/2 / 3/4 = 2/3
近似値¶
Fraction の便利な機能は、分母の大きさを制限することで浮動小数の値から有理数の近似値に変換する機能です。
import fractions
import math
print 'PI =', math.pi
f_pi = fractions.Fraction(str(math.pi))
print 'No limit =', f_pi
for i in range(1, 100, 5):
limited = f_pi.limit_denominator(i)
print '{0:8} = {1}'.format(i, limited)
$ python fractions_limit_denominator.py
PI = 3.14159265359
No limit = 314159265359/100000000000
1 = 3
6 = 19/6
11 = 22/7
16 = 22/7
21 = 22/7
26 = 22/7
31 = 22/7
36 = 22/7
41 = 22/7
46 = 22/7
51 = 22/7
56 = 22/7
61 = 179/57
66 = 201/64
71 = 223/71
76 = 223/71
81 = 245/78
86 = 267/85
91 = 267/85
96 = 289/92