Python decimalのgetcontext()とは?計算精度を設定する方法
getcontext()は、Decimalの計算設定(コンテキスト)を取得する関数です。
有効桁数や丸め方など、すべてのDecimal演算に共通する挙動をここで決めます。
現在の設定を見る
from decimal import getcontext
c = getcontext()
print("prec :", c.prec)
print("rounding:", c.rounding)
実行結果:
prec : 28
rounding: ROUND_HALF_EVEN
主な項目は次の2つです。
| 項目 | 既定値 | 意味 |
|---|---|---|
prec |
28 | 有効桁数 |
rounding |
ROUND_HALF_EVEN |
丸め方 |
precは「有効桁数」
ここを誤解しやすいので注意してください。precは小数点以下の桁数ではありません。
from decimal import Decimal, getcontext
getcontext().prec = 5
print(Decimal(1) / Decimal(3))
print(Decimal(12345) + Decimal(1))
print(Decimal(123456) + Decimal(1))
実行結果:
0.33333
12346
1.2346E+5
3行目に注目してください。整数の計算なのに指数表記になり、下の桁が失われています。
123457は6桁あり、prec=5に収まらないためです。
精度を絞ると、大きな整数の計算まで壊れます。安易に小さくしないでください。
precが効くタイミング
getcontext().prec = 3
print(Decimal('1.23456'))
print(Decimal('1.23456') + 0)
実行結果:
1.23456
1.23
作っただけでは丸まりません。演算した瞬間にprecが適用されます。
「値を保持するときは元のまま、計算結果は指定桁に丸める」という設計です。
影響範囲を限定する
from decimal import Decimal, localcontext
with localcontext() as ctx:
ctx.prec = 3
print("中:", Decimal(1) / Decimal(3))
print("外:", Decimal(1) / Decimal(3))
実行結果:
中: 0.333
外: 0.3333333333333333333333333333
getcontext()の変更はプログラム全体に効きます。ライブラリの内部処理まで巻き込みます。
一時的に変えたいだけならlocalcontext()を使ってください。withを抜けると自動で元に戻ります。
スレッドごとに独立している
import threading
from decimal import getcontext
def show():
print("子スレッド:", getcontext().prec)
getcontext().prec = 7
t = threading.Thread(target=show)
t.start()
t.join()
print("親スレッド:", getcontext().prec)
実行結果:
子スレッド: 28
親スレッド: 7
設定は引き継がれません。各スレッドが自分のコンテキストを持ちます。
スレッドを使う処理では、ワーカーの中で設定し直す必要があります。これを忘れると、メインでは合っているのにワーカーの結果だけ違う、という事故になります。
「Python threadingとは?スレッド処理の基本を解説」も参照してください。
trapsでエラーの扱いを変える
from decimal import Decimal, DivisionByZero
Decimal(1) / Decimal(0)
実行結果:
decimal.DivisionByZero: [<class 'decimal.DivisionByZero'>]
既定ではゼロ除算が例外になります。これをInfinityを返す動作に変えられます。
from decimal import Decimal, localcontext, DivisionByZero
with localcontext() as ctx:
ctx.traps[DivisionByZero] = False
print(Decimal(1) / Decimal(0))
実行結果:
Infinity
実務では既定のまま(例外)にしておくほうが安全です。Infinityが紛れ込むと、どこで壊れたか追跡できなくなります。
触らないという選択
多くの場合、getcontext()を変更する必要はありません。
- 桁をそろえたい →
quantize()を使う - 四捨五入したい →
rounding=ROUND_HALF_UPを都度指定 - 金額計算 → 既定の28桁で十分
個別の演算で明示するほうが、読む人にとって分かりやすくなります。グローバル設定はどこで変えられたか追いにくいためです。
quantize()は「Python Decimalのquantize()とは?小数の桁を丸める方法」を参照してください。
getcontext()のまとめ
- Decimal演算共通の設定を取得する
precは有効桁数——小数点以下の桁数ではない- 絞りすぎると大きな整数の計算まで壊れる
- 適用されるのは演算した時点
- 一時変更は
localcontext()で - スレッド間で引き継がれない
- 基本は触らず、
quantize()で都度指定する



