.NET開発者のためのブログメディア
Pythonでのdecimalモジュールの扱い方とは?演算誤差を防ぐためのdecimal
- SE
- decimaiモジュールとはどんな機能なのでしょうか?
- PM
- 十進数の計算を行うためのモジュールです。実際に詳しくみていきましょう。
目次
Pythonでのdecimalモジュールの扱い方とは?
今回は、Pythonでのdecimalモジュールの扱い方について説明します。
小数点を扱う場合、float型を使用します。
コンピュータは2進数で数値を扱うため、誤差が発生する場合があります。
これを防ぐために、Pythonではdecimalモジュールが用意されています。
ここでは、decimalモジュールの
・基本的な使い方
・演算
・FloatOperationのtrap
・精度の指定
・四捨五入(round)
・四捨五入(quantize)
について紹介します。
Pythonでのdecimalモジュールの扱い方に興味のある方はぜひご覧ください。
基本的な使い方
Pythonでのdecimalモジュールの基本的な使い方を紹介します。
decimalモジュールを使用するにはimportが必要です。
1
|
from decimal import Decimal
|
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
from decimal import Decimal
# floatの計算
f1 = 0.1
f2 = 0.2
f3 = f1 + f2
# decimalの計算
d1 = Decimal("0.1")
d2 = Decimal("0.2")
d3 = d1 + d2
print(f3) # 0.30000000000000004
print(d3) # 0.3
print(f3 == d3) # False
|
実行結果は以下のようになります。
1
2
3
|
0.30000000000000004
0.3
False
|
float型で計算した場合は、誤差が生じています。
一方、decimalモジュールで計算した場合、誤差が生じていません。
Decimalクラスには、文字列を指定する必要があります。
このようにdecimalモジュールを使用します。
演算
Pythonでのdecimalモジュールを使った演算について紹介します。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
|
from decimal import Decimal
d1 = Decimal("0.1")
d2 = Decimal("0.2")
print(d1 + d2) # 0.3
print(d1 - d2) # -0.1
print(d1 * d2) # 0.02
print(d1 / d2) # 0.5
|
実行結果は以下のようになります。
1
2
3
4
|
0.3
-0.1
0.02
0.5
|
このように、誤差なく加減乗除の演算ができます。
FloatOperationのtrap
Decimalクラスには、文字列を指定する必要があります。
数値を指定してもエラーにはなりません。
演算結果はどのようになるのでしょうか。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
|
from decimal import Decimal
d1 = Decimal(0.1)
d2 = Decimal(0.2)
print(d1 + d2) # 0.3000000000000000166533453694
|
実行結果は以下のようになります。
1
|
0.3000000000000000166533453694
|
数値で指定すると、誤差が生じていることが分かります。
間違って数値で指定することを防ぐために、FloatOperationのtrapを有効にする方法があります。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
|
from decimal import Decimal, getcontext, FloatOperation
# FloatOperationのtrapを有効にする
getcontext().traps[FloatOperation] = True
# float初期化で実行時エラー
d1 = Decimal(0.1)
# floatの演算で実行時エラー
d2 = Decimal(2) * 0.5
|
実行結果は以下のようになります。
1
2
3
4
|
Traceback (most recent call last):
File "Main.py", line 7, in <module>
d1 = Decimal(0.1)
decimal.FloatOperation: [<class 'decimal.FloatOperation'>]
|
Decimalをfloatで初期化したり、Decimalをfloatで計算すると、実行時エラーが発生します。
このように、PythonではFloatOperationのtrapを有効にすることで、意図しない初期化や演算を防げます。
精度の指定
Pythonでのdecimalモジュールを使った、精度を指定した演算について紹介します。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
|
from decimal import Decimal, getcontext
# 文字列ではなく、floatを指定
d1 = Decimal(0.1)
d2 = Decimal(0.2)
print(d1 + d2) # 0.3000000000000000166533453694
# 精度の指定
getcontext().prec = 5
print(d1 + d2) # 0.30000
|
実行結果は以下のようになります。
1
2
|
0.3000000000000000166533453694
0.30000
|
「getcontext().prec」で精度を指定することで、演算結果が指定精度で出力されていることが分かります。
このように、Pythonでは精度を指定した演算ができます。
四捨五入(round)
Pythonでのdecimalモジュールを使った丸めについて紹介します。
組み込み関数のroundメソッドを使用します。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
|
f = 123.456
print(round(f)) # 123
print(round(f, 1)) # 123.5
print(round(f, 2)) # 123.46
print(round(f, 3)) # 123.456
print(round(f, 0)) # 123.0
print(round(f, -1)) # 120.0
print(round(f, -2)) # 100.0
|
実行結果は以下のようになります。
1
2
3
4
5
6
7
|
123
123.5
123.46
123.456
123.0
120.0
100.0
|
小数を任意の桁数で四捨五入したり、整数を任意の桁数で四捨五入したりできます。
このように、組み込み関数のroundメソッドで四捨五入できます。
四捨五入(quantize)
Pythonでのdecimalモジュールを使った丸めについて、もう一つの方法を紹介します。
decimal標準ライブラリのquantizeメソッドを使用します。
実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from decimal import *
d1 = Decimal("123.456")
print(d1.quantize(Decimal("0"),rounding=ROUND_HALF_UP)) # 123
# 小数部の四捨五入
print(d1.quantize(Decimal("0.1"),rounding=ROUND_HALF_UP)) # 123.5
print(d1.quantize(Decimal("0.01"),rounding=ROUND_HALF_UP)) # 123.46
print(d1.quantize(Decimal("0.001"),rounding=ROUND_HALF_UP)) # 123.456
# 整数部の四捨五入
print(d1.quantize(Decimal("1E1"),rounding=ROUND_HALF_UP)) # 1.2E+2
print(d1.quantize(Decimal("1E2"),rounding=ROUND_HALF_UP)) # 1E+2
print(d1.quantize(Decimal("1E3"),rounding=ROUND_HALF_UP)) # 0E+3
# 整数部の四捨五入(intにして見やすく)
print(int(d1.quantize(Decimal("1E1"),rounding=ROUND_HALF_UP))) # 120
print(int(d1.quantize(Decimal("1E2"),rounding=ROUND_HALF_UP))) # 100
print(int(d1.quantize(Decimal("1E3"),rounding=ROUND_HALF_UP))) # 0
|
実行結果は以下のようになります。
1
2
3
4
5
6
7
8
9
10
|
123
123.5
123.46
123.456
1.2E+2
1E+2
0E+3
120
100
0
|
整数部の四捨五入は少し特殊です。
このように、Pythonではquantizeメソッドで四捨五入できます。
- SE
- 精度を指定できるということは、小数点も定義できるいうことでしょうか?
- PM
- そうです。文字列として定義することで誤差の発生も防ぐことができます。
まとめ
Pythonでのdecimalモジュールの扱い方について説明しました。
基本的な使い方だけでなく、演算精度の指定方法や四捨五入の方法なども紹介しました。
ぜひご自身でソースコードを書いて、理解を深めてください。
Search キーワード検索
Popular 人気の記事
reccomended おすすめ記事
Categories 連載一覧
Tags タグ一覧
Jobs 新着案件
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅)