decimal必须用字符串初始化,否则float解析已引入误差;pandas默认将字符串数字转为float64导致精度丢失,应先dtype=str再转decimal;quantize()需显式指定舍入策略,且decimal不兼容主流ai框架,仅限高精度中间计算。

直接用 Decimal 替换 float 做关键计算,但必须全程字符串初始化,否则精度在进 Decimal 前就丢了。
为什么 pandas 读数后一算就错?
pandas 默认把数字列转成 float64,哪怕源数据是 "1.23" 这种看着很干净的字符串。一旦进 float,0.1 变成 0.10000000000000000555,后续所有加减乘除都在这个“近似值”上叠误差。
- 读取时加
dtype={'col': 'string'},先保真再转Decimal - 或用
pd.read_csv(..., decimal=',', converters={'col': lambda x: Decimal(x)}),但注意传入必须是字符串,Decimal(1.23)和Decimal('1.23')结果完全不同 - 别依赖
round(df['col'], 2)—— 它只是格式化显示,底层还是 float
Decimal 四舍五入行为不等于 round()?
round() 在 Python 中对 .5 的处理是“四舍六入五成双”(银行家法则),但 Decimal.quantize() 默认也是 ROUND_HALF_EVEN,行为一致;不过很多人误用 ROUND_HALF_UP 却没显式指定,结果和预期不符。
Python 3.14.2是Python编程语言在2025年12月5日发布的稳定版本,属于3.14系列的第二个维护更新。该版本包含了18项修复,重点解决了多进程、数据类及正则表达式等模块的回归问题,并修复了CVE-2025-12084等安全漏洞。此版本标志着自由线程模式(移除GIL)正式获得官方支持,是Python发展的重要里程碑。
- 要严格四舍五入:用
Decimal('x').quantize(Decimal('0.01'), rounding=ROUND_HALF_UP) - 要银行家法则(推荐用于财务):默认即可,或显式写
ROUND_HALF_EVEN - 要截断(非四舍五入):用
ROUND_DOWN,比如Decimal('1.999').quantize(Decimal('0.1'), rounding=ROUND_DOWN)→1.9
模型训练时还能用 Decimal 吗?
不能。scikit-learn、XGBoost、PyTorch 等框架底层是 C/C++/CUDA,只认 numpy.ndarray,而 numpy 不支持 Decimal。硬塞会报 TypeError: array() got an unexpected keyword argument 'dtype' 或静默转成 float。
- 精度敏感环节(如特征工程中的金额分摊、比例计算、阈值判定)用
Decimal处理,输出再转float或int - 模型输入统一用
np.float64,但确保转换前已完成所有高精度中间计算 - 如果模型输出需回写到账务系统,务必在写入前用
Decimal校验并重格式化,别信 float 输出的最后一位小数
最易被忽略的是:Decimal 的上下文精度(getcontext().prec)默认是 28,但 pandas 的 to_numeric() 或 sklearn 的 StandardScaler 会悄悄把 Decimal 转成 float —— 这个转换点就是精度无声丢失的入口。要么绕开,要么在转换前后加 assert 检查。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










