Python
 Computer >> コンピューター >  >> プログラミング >> Python

【Python入門】fractionsモジュールで分数を正確に扱う方法


Pythonのfractionsモジュールは、有理数(分数)の演算をサポートする標準ライブラリです。このモジュールを利用すると、整数・浮動小数点数・Decimal型・さらには文字列など、さまざまな数値から分数(Fraction)オブジェクトを作成できます。

Fractionインスタンスは、分子と分母のペアとなる2つの整数で構成されます。

Fractionクラスの基本

fractions.Fractionクラスを使うと、Fractionオブジェクトを作成できます。このクラスは分子(numerator)と分母(denominator)を受け取り、デフォルト値はそれぞれ0と1です。分母に0を指定した場合はZeroDivisionErrorが発生するので注意してください。

まずは、分子と分母を指定して分数を作成する基本形を見てみましょう。

サンプルコード

from fractions import Fraction as frac
print(frac(45, 54))
print(frac(12, 47))
print(frac(0, 15))

出力結果

5/6
12/47
0

45/54は自動的に約分されて5/6になっています。Fractionクラスは常に既約分数(最も簡単な形)を保持するためです。

浮動小数点数と文字列で結果が変わる理由

Fractionオブジェクトには浮動小数点数も引数として渡せます。ただし、浮動小数点数は内部で2進数として表現されるため、厳密な値ではなく近似値に変換され、分子・分母が非常に大きな整数になることがあります。一方、文字列として渡した場合は、表記どおりの正確な分数が得られます。次の例で違いを確認しましょう。

サンプルコード

from fractions import Fraction as frac
print(frac(33.33))
print(frac('33.33'))

出力結果

2345390243441541/70368744177664
3333/100

文字列引数のさまざまな指定方法

文字列引数では「5/6」のような分数表記も使用できます。さらに、+や-の符号にも対応しており、タブや改行などの空白文字が含まれていても正しくパースされます。

サンプルコード

from fractions import Fraction as frac
print(frac('5/6'))
print(frac('-25.12'))
print(frac('96.251 \t\n'))
print(frac('3.14159265359'))

出力結果

5/6
-628/25
96251/1000
314159265359/100000000000

limit_denominator()で分母の長さを制限する

これまで見たように、浮動小数点数から作成したFractionオブジェクトでは、分母が非常に大きな値になることがあります。limit_denominator()メソッドを使えば分母の上限を設定でき、デフォルトの上限は1000000です。これにより、浮動小数点データに対する有理数近似(円周率の22/7や355/113といった有名な近似値など)を簡単に求められます。

また、分数オブジェクト全体ではなく分子や分母だけが必要な場合は、numerator属性とdenominator属性で個別に取得できます。

サンプルコード

from fractions import Fraction as frac
print(frac('3.14159265359'))
print(frac('3.14159265359').limit_denominator(1000))
print(frac('3.14159265359').limit_denominator(100))
print(frac('3.14159265359').limit_denominator(10))
print(frac('36.25'))
print(frac('36.25').numerator)
print(frac('36.25').denominator)

出力結果

314159265359/100000000000
355/113
311/99
22/7
145/4
145
4

円周率に対してlimit_denominator()を適用すると、上限が10なら有名な近似値「22/7」、上限が1000ならより高精度な「355/113」が得られます。

四則演算とべき乗

Fractionオブジェクトは、加算・減算・乗算・除算・べき乗などの数学的演算をそのままサポートしています。

サンプルコード

from fractions import Fraction as frac
print('Add: ' + str(frac('5/4') + frac('9/8')))
print('Subtract: ' + str(frac('15/20') - frac('2/8')))
print('Multiply: ' + str(frac('2/3') * frac('5/7')))
print('Divide: ' + str(frac('80/125') / frac('12/45')))
print('Power: ' + str(frac('5/6') ** 3))

出力結果

Add: 19/8
Subtract: 1/2
Multiply: 10/21
Divide: 12/5
Power: 125/216

平方根・切り捨て・切り上げとの連携

Fractionオブジェクトは、mathモジュールの平方根(sqrt)、切り捨て(floor)、切り上げ(ceil)などの関数とも組み合わせられます。math.sqrt()の戻り値をfrac()に渡せば、結果を再び分数として扱うことも可能です。

サンプルコード

from fractions import Fraction as frac
import math
print('Square Root: ' + str(math.sqrt(frac(36, 64))))
print('Square Root: ' + str(frac(math.sqrt(frac(36, 64)))))
print('Floor Value: ' + str(math.floor(frac('22/7'))))
print('Ceiling Value: ' + str(math.ceil(frac('22/7'))))

出力結果

Square Root: 0.75
Square Root: 3/4
Floor Value: 3
Ceiling Value: 4

このようにPythonのfractionsモジュールを活用すれば、誤差のない有理数計算を手軽に実現できます。金額計算や厳密な数値処理が必要な場面で、ぜひ活用してみてください。


  1. Pythonでパターンを出力する方法|三角形・数字・アルファベット・ピラミッドのコード例

    Pythonでパターンを出力するには、ネストされた(入れ子構造の)forループを使用します。外側のループで行数を制御し、内側のループで列数を処理します。そしてprint文を工夫することで、目的に応じたさまざまなパターンを作成できます。パターンには、星(アスタリスク)パターン、数字パターン、アルファベットパターンなどがあり、三角形やピラミッドなど、さまざまな形状にも対応できます。パターン出力の基本これらのパターンは、print文を少し変更しながらforループを組み合わせることで出力できます。基本的な考え方はどのパターンも共通しており、違いはごくわずかです。ここからは、代表的なパターンのコードを実

  2. Pythonのgetpassモジュールとは?パスワード入力とユーザー名取得の基本を解説

    Pythonの標準ライブラリには、ターミナル上で動作するアプリケーションにおいて、ユーザーの認証情報を検証してから処理を実行したい場合に役立つgetpassモジュールが用意されています。このモジュールには主に2つの関数が定義されており、セキュリティを意識したコマンドラインツールの開発に欠かせない存在です。 getpass() 関数:パスワードを安全に入力する getpass()関数は、ユーザーにパスワードの入力を促すための関数です。デフォルトでは、ターミナルに入力されたキーは画面に表示(エコー)されないため、第三者にパスワードを盗み見られる心配がありません。 また、プロンプトとして表示される