Django

コンピューターが起こす少数点以下の誤差に気を付けよう!😆

昔、業務システムで電卓の計算結果とシステムが計算してくる結果が異なることがありました。日割り計算の結果でしたが、コンピューターは小数点以下の何桁目かを四捨五入で、数字をどこかで丸めて確定します

永遠に計算なんかやってられないからですね。

電卓は大体小数点12桁めを切り捨てしています。

このことによりまれに小数点での誤差が発生したりします。よくネットで調べてすぐに出てくるのは、1.1 という数字ですね。

浮動小数点で計算誤差が発生することを確認する

なんで浮動小数点で誤差が発生するかの原因は、10進数と2進数との変換時の都合なのです。

まぁ、それをしっかり理解する必要はないと思います。覚えておくことが必要なのは、

ポイント

お金の計算など、誤差の発生が許されないものなら、必ず小数点以下をどう扱うか指定しよう!

誤差があるか確認しよう

それでは、実際にパソコンで計算した時にそんな誤差が本当に発生しているかを確認しようと思います。

みてみよう

0.1 + 0.2 = 0.3 (これは人間ならだれでもできる!)

人ならこんな計算、暗算ですぐにできますよね。これを実際、パソコンで実行させてみましょう!

a = 0.1
b = 0.2

c = a + b

print(c)

これの実行結果は、

なんか、最後に4って数字が入ってますね…ぼくみたいに10億円持っている人の利息計算すると誤差が出てきて、利息が余計につくことになっちゃいますね。

あっ、すべて妄想です(笑)10億あってもプログラミングはしてるかもしてると思いますが

Python🐍で浮動小数点の誤差を回避する方法

Pythonでは、こういうことに対応するためのライブラリが公開されています。

それは、

decimal

です。

これは、日常で使っている10進数で計算をしてくれるようになる便利な道具っていう感じです。

まずは、Decimalをインポートします。

from decimal import Decimal

これでモジュールが入ります。便利ですよねーだれが作ってくれてるのかはわからないし、これは、どこからやってきてるのかも知りませんが、作成してくれた人に感謝です😄

インポートしたら、変数に値を入れる時に、

変数 = decimal.Decimal("1.1")

最初、間違えやすいのは、数字のままでいれるのではなく、シングルクォーテーション(')かダブルクォーテーション(")で囲むようにして入れる必要があります。

ポイント

Decimalを使用するときは、変数への代入時に ( ’ )シングルクォーテーション)か、( ” )ダブルクォーテーションをつけること

これをせずに代入すると、誤差が発生したまんまになるので気を付けてください。しかも小数点の桁数がもっとずれるしわけわからんことになってしまいます😅

コードはこんな感じになります。

from decimal import Decimal

a = Decimal(0.1)
b = Decimal(0.2)

c = a + b

print(c)

これを実行すると、

あー、これこれ!本当に、コンピューターってすごいんですが、小数点以下の取り扱いが苦手ってことだけは昔も今も変わらないから、意識して対応しておかないといけないですね!

多少の誤差が問題にならないような場合はいいのですが、普段から意識して使っておかないと忘れてしまうかもしれません。

ポイント

普段から、小数点以下を扱う時は、小数点誤差の対応を必ず意識してやろう!

小数点誤差の対応 まとめ

Pythonで簡単に対応するのは、decimal をつかうことです。

まとめ

  1. from decimal import Decimal でモジュールをインポート
  2. 変数に代入するときは、シングルクォーテーションかダブルクォーテーションをつける
  3. 小数点以下を扱う場合は、いつも意識して対応しておくこと

-Django

© 2021 ごろう@縁紡ぐ