☆youtube始めました☆

python~decimalで数値を丸める~【pythonマスターへの道#010】

_
decimalで数値を丸めるPython
この記事は約11分で読めます。

以前の記事で、decimalを使用した正確な計算を学びましたが、

decimalにはまだ数値の丸めという便利な機能があります。

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

「数値の丸め」と一言に言っても実はたくさんの種類があります。

一つ一つ理解してマスターしましょう!

自己紹介

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

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

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

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

pythonの数値の丸めの種類

decimalを使用して実際にできる数値の丸めの種類は、

  • ROUND_CEILING
  • ROUND_FLOOR
  • ROUND_UP
  • ROUND_DOWN
  • ROUND_HALF_DOWN
  • ROUND_HALF_EVEN
  • ROUND_HALF_UP

これだけ豊富に存在します。

それぞれの使い方と具体例を学びましょう。

ROUND_CEILING

ROUND_CEILINGの使い道

ROUND_CEILINGは、「プラス方向への切り上げ」です。

decimalの使い方でやった、contextプロパティの指定で

「プラス方向への切り上げ」ができるようになります。

ROUND_CEILINGの具体例

それでは、10/3の答え、3.33333を例にして

ROUND_CEILINGを使用してみましょう。

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_CEILING #有効桁数の所でプラス方向に切り上げ
x=decimal.Decimal('10')/decimal.Decimal('3')
print(x)

decimalを使用するときはimport decimalを忘れないように気を付けてください。

出力結果は、3.334になりましたね?

有効桁数4で、4桁目を「プラス方向へ切り上げ」しているので

3.333333…. ⇒ 3.334となっています。

ちなみに、負の数字にROUND_CEILINGを使用したばあいは、

「切り捨て」のような扱いになります。

具体的には、

-3.33333333… ⇒ -3.333(有効桁数4で指定)

となります。

ROUND_FLOOR

ROUND_FLOORの使い道

次にROUND_FLOORです。

こちらは、「マイナス方向への丸め」になります。

ROUND_CEILINGのちょうど逆といったところですね。

ROUND_FLOORの具体例

同様の例に使用してみると、

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_FLOOR #有効桁数の所でマイナス方向に丸め
x=decimal.Decimal('-10')/decimal.Decimal('3')
print(x)

出力結果は、-3.334となります。

正の数字にROUND_FLOORを使用すると、

ちょうどROUND_CEILINGの負の数字と同じように、

「切り捨て」のような処理が行われます。

具体的には、

3.333333…. ⇒ 3.333(有効桁数4)

となります。

ROUND_UP

ROUND_UPの使い道

ROUND_UPは正の数字でも、負の数字でも、

切り上げ処理が行われます。

3.3333…⇒3.334

-3.33333…⇒-3.334

ROUND_CEILINGとROUND_FLOORでは、

正か負かによって「切り捨て」が行われていましたが、

それが無いパターンですね。

ROUND_UPの具体例

なんとなく予想はつくと思いますが、

コードを書いておきます。出力結果は3.334です。

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_UP #有効桁数の所でプラス方向に切り上げ
x=decimal.Decimal('10')/decimal.Decimal('3')
print(x)

ROUND_DOWN

ROUND_DOWNの使い道

ROUND_DOWNは、ROUND_UPの逆です。

つまり、正負にかかわらず、有効桁数で切り捨てします。

ROUND_DOWNの具体例

負の数をROUND_DOWNした場合、

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_DOWN #有効桁数の所でプラス方向に切り上げ
x=decimal.Decimal('-10')/decimal.Decimal('3')
print(x)

-3.333が出力結果となります。

-10を10として、正の数にしたばあいでも

「切り捨て」の処理をされるので、

3.333が出力されます。

ROUND_HALF_DOWN

ROUND_HALF_DOWNの使い道

ROUND_HALF_DOWNは、有効桁数の末尾が0~5と6~9で

処理が変わります。

具体例を見たほうが早いので、具体例をご覧ください。

ROUND_HALF_DOWNの具体例

ここでは、10から小さい値を引いて切り上げされるのか、

切り捨てされるのか確認します。

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_DOWN #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0006')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_DOWN #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0005')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_DOWN #有効桁数の所が6~9なら切り上げ
x=decimal.Decimal('10')-decimal.Decimal('0.0004')
print(x)

出力結果は、順に

9.999

9.999

10.00となります。

ですから、有効桁数4とした場合には、

9.9994⇒9.999

9.9995⇒9.999

9.9996⇒10.00

という出力結果となります。

イメージとしては、四捨五入ではなく、五捨六入というイメージでしょうか。

ROUND_HALF_EVEN

ROUND_HALF_EVENの使い道

ROUND_HARLF_EVENは、

先ほどのROUND_HALF_DOWNとは、

有効桁数の末尾が5の時の扱いのみ異なります。

ROUND_HALF_EVENの具体例

先ほどのROUND_HALF_DOWNと同様の具体例で

どうなるか確認してみましょう。

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_EVEN #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0006')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_EVEN #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0005')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_EVEN #有効桁数の所が6~9なら切り上げ
x=decimal.Decimal('10')-decimal.Decimal('0.0004')
print(x)

出力結果は、順に

9.999

10.00

10.00

なので、ROUND_HALF_DOWNとは、末尾が5の場合のみ異なりました。

ただじつは、このHALF_UPとHALF_DOWN

CEILINGとFLOORの関係のように、

正の数を丸めるか、負の数を丸めるかで挙動が変わりますので、

完全な四捨五入とはいきません。

正の数であれば、ROUND_HALF_EVENが四捨五入になっているのは

確認できましたが…

ROUND_HALF_UP(四捨五入)

ROUND_HALF_UPの使い道

ROUND_HALF_UPは、

ROUND_HALF_DOWNとEVENの四捨五入のみできるようにしたものです。

先ほど、正の数であれば、ROUND_HALF_EVENが

四捨五入になるお話はしましたが、

負の数でも四捨五入になるようにしてあるのが、

このROUND_HALF_UPです。

ROUND_HALF_UPの具体例

例としては、「10から小さい値を引くパターン」と、

「-10から小さい値を足すパターン」の2種類で見ていきましょう。

import decimal
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0006')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('10')-decimal.Decimal('0.0005')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が6~9なら切り上げ
x=decimal.Decimal('10')-decimal.Decimal('0.0004')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('-10')+decimal.Decimal('0.0006')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が0~5なら切り捨て
x=decimal.Decimal('-10')+decimal.Decimal('0.0005')
print(x)
cont=decimal.getcontext() #decimalのContextプロパティを取得
cont.prec=4 #有効桁数を指定
cont.rounding=decimal.ROUND_HALF_UP #有効桁数の所が6~9なら切り上げ
x=decimal.Decimal('-10')+decimal.Decimal('0.0004')
print(x)

出力結果は、順に

9.999

10.00

10.00

-9.999

-10.00

-10.00

となったので、正の数でも、負の数でも四捨五入されているのがわかります。

まとめ

今回は、decimalを使用した数値の丸めについて学びました。

四捨五入以外にも、切り捨てや切り上げなどの処理が必要になることは

多々あると思います。

そのときに向けてしっかりと違いについて理解しておきましょう。


独学の限界を感じているあなた。

昨今のトレンドに乗り遅れていませんか?

「苦労して少ない情報をネット検索するのはもうやめましょう。」

プログラミング習得のテッパンはずばりスクールです。

「無料でpythonの基礎」を習得しませんか?

すでに1万人以上が受講している人気講座です。

時代のトレンドに乗り遅れる前に今のうちに習得しておきませんか??

コメント

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