要使用 Python 的 Decimal 模組來避免浮點數精度問題,最關鍵的原則只有一個:絕對不要用浮點數(float)去初始化 Decimal,一定要用「字串(string)」。
🚫 核心地雷:為什麼不能用 float 初始化?
如果你直接用浮點數建立 Decimal,你會把浮點數原本的誤差「完美繼承」下來,這樣就失去了使用 Decimal 的意義。。
- 錯誤示範(踩雷):
Python
from decimal import Decimal
# 0.1 在二進制中本來就不精確,Decimal 會忠實記錄這個不精確的值
num = Decimal(0.1)
print(num)
# 輸出: 0.1000000000000000055511151231257827021181583404541015625
- 正確示範(推薦):
Python
from decimal import Decimal
# 使用字串,Decimal 會精確解析字面上的數值
num = Decimal('0.1')
print(num)
# 輸出: 0.1正確示範(推薦):
🛠️ 實戰步驟:如何正確使用
1. 基本運算(解決 0.1 + 0.2 問題)
只要堅持使用字串初始化,基本的加減乘除就會自動變得精確。
python编辑
from decimal import Decimal
a = Decimal('0.1')
b = Decimal('0.2')
# 結果完全精確
print(a + b) # 輸出: 0.3
print(a * 3) # 輸出: 0.3
2. 控制精度與捨入(金融計算必備)
在金融場景中,我們通常需要固定小數位數(例如 2 位),並指定捨入規則(例如四捨五入)。這時要用到 quantize() 方法。
python编辑
from decimal import Decimal, ROUND_HALF_UP
price = Decimal('19.99')
tax_rate = Decimal('0.05')
total = price * tax_rate # 結果是 0.9995
# 使用 quantize 強制保留 2 位小數,並四捨五入
# ROUND_HALF_UP 代表「四捨五入」(0.5 進位)
final_price = total.quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
print(final_price) # 輸出: 1.00
3. 設定全域精度(科學計算用)
如果你需要計算圓周率或進行高精度除法,可以透過 getcontext() 設定全域的有效位數。
python编辑
from decimal import Decimal, getcontext
# 設定全域精度為 50 位有效數字
getcontext().prec = 50
result = Decimal('1') / Decimal('3')
print(result)
# 輸出: 0.33333333333333333333333333333333333333333333333333
📊 浮點數 vs. Decimal 對比

💡 進階技巧:如何處理現有的 float 變數?
如果你的數據來源已經是 float(例如從舊系統讀取),該怎麼轉成 Decimal?
方法一:先轉字串(最推薦)
python编辑
float_val = 0.1
# 先轉字串再轉 Decimal,避免誤差
safe_decimal = Decimal(str(float_val))
方法二:使用整數(最精確)
如果是金額,建議直接用「分」為單位計算,最後再轉 Decimal。
python编辑
# 表示 10.50 元
amount = Decimal(1050) / Decimal(100)
📌 總結建議
要在 Python 中避免精度問題,請記住這句口訣:「金錢用 Decimal,初始化用字串,捨入用 quantize。」


















