2.5を整数へ丸めると、方式によって2にも3にもなります。どちらが正しいかは、計算前に決めた端数処理の条件によります。Pythonで金額や単価を扱うなら、使う関数に任せきりにせず、どの桁をどの方式で丸めるかを指定します。
標準ライブラリのDecimalは十進の数を扱うための道具です。文字列から値を作り、quantizeで丸める桁と方式を渡すと、例外となる値も確認しやすくなります。
中間の値と負数を比べる
下の例では小数第一位の値を整数へ丸めます。ROUND_HALF_UPは中間ならゼロから遠い側、ROUND_HALF_EVENは中間なら偶数側を選ぶ方式です。2.5だけでなく、3.5と-2.5も並べます。
from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_EVEN
unit = Decimal("1")
for text in ["2.5", "3.5", "-2.5"]:
value = Decimal(text)
up = value.quantize(unit, rounding=ROUND_HALF_UP)
even = value.quantize(unit, rounding=ROUND_HALF_EVEN)
print(text, "UP=", up, "EVEN=", even)
total = Decimal("0.1") + Decimal("0.2")
print("0.1 + 0.2 =", total)
assert Decimal("2.5").quantize(unit, rounding=ROUND_HALF_UP) == 3
assert Decimal("-2.5").quantize(unit, rounding=ROUND_HALF_UP) == -3
assert total == Decimal("0.3")
2.5はUPで3、EVENで2になります。3.5は両方4、-2.5はUPで-3、EVENで-2です。小数部分が5だから常に数直線の大きい方へ進む、と覚えると負数で取り違えます。
掲載例はWindows・Python 3.12.10で実行しました。上の値について結果を確認したもので、特定の帳票や業務の端数処理を検証したわけではありません。
Decimalは元の文字列から作る
Decimal("0.1")のように、入力時の文字列を渡します。Decimal(0.1)ではすでにfloatとして持っている二進浮動小数点数の値をDecimalへ変換します。元の十進表記を自動で復元する指定ではありません。
CSVから読んだ金額なら、文字列を保持したまま形式を検査してDecimalへ渡す方法があります。空欄、通貨記号、桁区切りなどをどこまで許可するかも、その列の仕様に合わせます。
一度floatで計算してから最後だけDecimalへ直すと、途中で生じた表現の差も受け取ります。厳密な十進計算が必要な部分は、入り口から計算の途中まで同じ方針にそろえてください。大きな桁数ではDecimal側の計算精度も別に確認します。
丸める桁と順序を決める
quantizeへ渡すDecimal("1")は整数の桁、Decimal("0.01")は小数第二位まで残す指定です。見せたい桁数と、計算に残す桁数を区別すると、表示のためだけの丸めを途中計算へ混ぜずに済みます。
各明細を丸めてから合計するか、合計してから丸めるかでも結果は変わります。0.5を二件、整数へHALF_UPで丸めるなら、明細ごとでは1と1で合計2、先に合計すれば1です。処理の順序も入力仕様の一部として残します。
税務、会計、契約などで採用する方式は、担当者や適用される基準に確認してください。このページは計算方法の違いを確かめる例であり、どの業務にも同じ丸め方を勧めるものではありません。
CSVの合計と検算はCSV集計の基本、入力文字の整理はPythonの文字列操作で確認できます。
仕様の確認先
Decimalの生成とquantize、丸め方式はPython decimal公式資料を参照しました。資料確認日は2026年11月1日です。
