【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モジュールを活用すれば、誤差のない有理数計算を手軽に実現できます。金額計算や厳密な数値処理が必要な場面で、ぜひ活用してみてください。
-
Pythonでパターンを出力する方法|三角形・数字・アルファベット・ピラミッドのコード例
Pythonでパターンを出力するには、ネストされた(入れ子構造の)forループを使用します。外側のループで行数を制御し、内側のループで列数を処理します。そしてprint文を工夫することで、目的に応じたさまざまなパターンを作成できます。パターンには、星(アスタリスク)パターン、数字パターン、アルファベットパターンなどがあり、三角形やピラミッドなど、さまざまな形状にも対応できます。パターン出力の基本これらのパターンは、print文を少し変更しながらforループを組み合わせることで出力できます。基本的な考え方はどのパターンも共通しており、違いはごくわずかです。ここからは、代表的なパターンのコードを実
-
Pythonのgetpassモジュールとは?パスワード入力とユーザー名取得の基本を解説
Pythonの標準ライブラリには、ターミナル上で動作するアプリケーションにおいて、ユーザーの認証情報を検証してから処理を実行したい場合に役立つgetpassモジュールが用意されています。このモジュールには主に2つの関数が定義されており、セキュリティを意識したコマンドラインツールの開発に欠かせない存在です。 getpass() 関数:パスワードを安全に入力する getpass()関数は、ユーザーにパスワードの入力を促すための関数です。デフォルトでは、ターミナルに入力されたキーは画面に表示(エコー)されないため、第三者にパスワードを盗み見られる心配がありません。 また、プロンプトとして表示される