PR

python~decimalで浮動小数点数を正確に計算~【pythonマスターへの道#009】

decimal-calc

pythonで数値を扱っていると、

微妙な誤差によってとんでもない桁数の数字が出る事ありませんか?

今回はそんな数値の誤差ついて一緒に学んでいきましょう。

使用するものは、decimalと呼ばれるものです。

decimalを使用すれば、小数点以下の計算も正確に行えます。

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

今までのPythonに関する記事はこちら

pythonでそのまま計算させると誤差が出る

なんとなくあなたも実感しているかもしれませんが、

pythonでそのまま計算しても実は若干誤差がでます。

たとえば、0.1×0.1をするとき、

0.01と暗算されたと思いますが、

実際にpythonで計算させると、

print(0.1*0.1)

実は0.01にはならず、

0.010000000000000002

こんな感じで微小なゴミのような値がくっついてきます。

decimalを使って正確な計算を行う

先ほどの例のように、0.00000000…..2

という微小な値が含まれることによって、

大きな影響は考えにくいですが、

それでも0.1×0.1と計算したら、素直に0.01と出力してほしいですよね?

そこでdecimalの登場です。

ちょっと面倒ですが、掛け算するときの0.1に少し細工をします

import  decimal
x=decimal.Decimal('0.1')*decimal.Decimal('0.1')
print(x)

これで0.01が出力されます。

Point

import decimal←pythonをインストールすると標準で搭載されている「モジュール」です。

この一文を入れることによって、decimalを扱えるようになります。

decimalの使い方ですが、

decimal.Decimal(‘数字’)とすることで、浮動小数点数を正確に計算することができます。

‘(シングルコーテーション)で挟むことに注意してください。

桁数を指定して正確な計算を行う

それでは、桁数を指定して正確な計算を行いたい場合

どうするかご説明します。

たとえば、0.1/0.3をしたい場合。

普通にやると…

x=0.1/0.3
print(x)

この場合の出力は、

0.33333333333333337

相変わらず微小な値の違いが見て取れます。

最後の7ってなんだよって話ですね。

それでは先ほど学んだdecimalを使用して正確な計算をした場合、

import  decimal
y=decimal.Decimal('0.1')/decimal.Decimal('0.3')
print(y)

この出力は、

0.3333333333333333333333333333

確かに「正確」にはなりましたが、

ちょっと桁が長すぎますね。

ですから、出力される桁数を制限します。

decimalの桁数の指定方法

まずは桁数を指定するコードを示します。

import  decimal
cont=decimal.getcontext() #contextを取得
cont.prec=2 #contextの有効桁数を2に指定
y=decimal.Decimal('0.1')/decimal.Decimal('0.3')
print(y)

この場合だと、decimalのcontextに2を入れているので、

有効桁数2桁。つまり、0.33と出力されます。

Point

decimal.getcontext()で、contextをいったん取得しています。

contextとは、decimalに含まれるプロパティのような物です。

そのcontextのprecというパラメータを指定することによって、

有効桁数を制限可能となります。

y=の式の中で有効桁数を指定しないのが、

ちょっと気持ち悪い気もしますが、とりあえずこれで有効桁数の指定完了です。

まとめ

今回はdecimalを使用して、

正確な(誤差の乗らない)計算を学びました。

次回は、decimalを使用して数値の切り捨て、切り上げなどの

丸めについても一緒に学んでいきます。

コメント

タイトルとURLをコピーしました