decimalでのrounding(丸め方)について調べてみましたよ

社内SNSで毒づいてみるテストや、毎日書籍を1冊読むことに必死になるあまり、ブログを更新できていないbonlifeです。
さてさて、10進数を上手いこと扱ってくれるPythonの素敵モジュールの使い方を紹介している日記に以下のような記述があったので、ちょっと整理してみました。

丸め用の定数は上記の3つ(ROUND_UP、ROUND_DOWN、ROUND_HALF_UP)以外にも

ROUND_CEILING, ROUND_FLOOR, ROUND_HALF_DOWN, ROUND_HALF_EVENがあるようだが、ちがいが良く分からない。

確かに混乱しますよね。ということで、(あまり調べずに)私の(個人的な)理解を書いてみました。「ちょ、それ違うよ!!」ってご指摘お待ちしております。

rounding bonlife勝手解釈
ROUND_UP 0 から離れるように丸める
ROUND_DOWN 0 に近づくように丸める
ROUND_CEIL 数値として大きい方(天井方向)に丸める
ROUND_FLOOR 数値として小さい方(床方向)に丸める
ROUND_HALF_UP 四捨五入
ROUND_HALF_DOWN 五捨六入
ROUND_HALF_EVEN 5 の場合に偶数(EVEN)になるように丸める

ROUND_UP と ROUND_CEIL、ROUND_DOWN と ROUND_FLOOR はよく似てるのですが、負数の場合の動作が逆になるんです。とか言葉で説明してもアレなので、久々にコードを書いてみました。

  • decimal_rounding_check.py
from decimal import *

def decimal_rounding_check():
    """print results of decimal module's quantize method.
       setting : quantize(Decimal('1.'))
       range   : 0.0 to 9.9 and -0.0 to -9.9"""
    roundings = [ROUND_UP, ROUND_DOWN,
                 ROUND_CEILING, ROUND_FLOOR,
                 ROUND_HALF_UP, ROUND_HALF_DOWN,
                 ROUND_HALF_EVEN]
    # header information
    header = "ORIGINAL"
    for r in roundings:
        header += "\t%s" % r
    print header
    # 0.0 to 9.9
    for i in xrange(10):
        for j in xrange(10):
            org  = "%s.%s" % (i,j)
            line = org
            for r in roundings:
                result = Decimal(org).quantize(Decimal('1.'),rounding=r)
                line += "\t%s" % result
            print line
    # -0.0 to -9.9
    for i in xrange(10):
        for j in xrange(10):
            org  = "-%s.%s" % (i,j)
            line = org
            for r in roundings:
                result = Decimal(org).quantize(Decimal('1.'),rounding=r)
                line += "\t%s" % result
            print line

if __name__ == "__main__":
    decimal_rounding_check()

タブ区切りでprintしてますので、出力結果をファイルにリダイレクトして、EXCELなどに貼り付けるとナイスだと思います。(皆さんご存知だと思いますが、EXCELの場合、事前に書式設定を変更して"文字列"にしておかないと、1.0 とかが勝手に 1 にされちまいますのでご注意あれ。)
一人でも「ふーん。」って思ってくれる人がいたら、これ幸い。