Python中round()仅四舍五入,无法截断小数;需用math.floor(x*100)/100实现向下截断(负数也正确),或decimal.Decimal.quantize(..., rounding=ROUND_DOWN)确保金融级精度。
round() 不能截断小数,它默认四舍五入很多人误以为 round(3.145, 2) 能“控制两位小数”,但其实它会四舍五入成 3.15;更关键的是,当目标是「截断」(即直接砍掉第三位及之后,不进位)时,round() 完全不适用。比如 round(1.239, 2) → 1.24,而你想要的是 1.23。
math.floor() 配合缩放实现向下截断核心思路:把数字放大 100 倍 → 向下取整 → 再除以 100。注意必须用 math.floor()(不是 int()),否则负数会出错(int(-1.239 * 100) 是 -123,但 math.floor(-123.9) 才是 -124,这才是真正向下截断)。
math.floor(1.239 * 100) / 100 → 123.0 / 100 → 1.23
math.floor(-1.239 * 100) / 100 → math.floor(-123.9) → -124.0 / 100 → -1.24(符合“向负无穷截断”语义)int(x * 100) / 100,但要清楚这在负数上不是数学意义的截断直接 s 然后找小数点位置切片,看似直观,但 Python 浮点数二进制存储会导致意外结果。例如 
str(1.005) 可能返回 '1.0049999999999999',切出的就不是 '1.00' 而是 '1.00' 或 '1.01',完全不可控。
decimal 处理过)math.floor 方案)s = f"{x:.10f}"; i = s.find('.'); s[:i+3] if i != -1 else s —— 但 .10f 不保底,仍可能暴露精度问题decimal.Decimal 是最稳妥的金融级方案当精确性不可妥协(比如金额计算),必须用 decimal。它支持明确的舍入策略,包括 ROUND_DOWN(即截断)。
Decimal:from decimal import Decimal, ROUND_DOWN; d = Decimal(str(x))(注意:必须用 str(x) 构造,避免 float 二进制误差)d.quantize(Decimal('0.01'), rounding=ROUND_DOWN)
float(d.quantize(...)) 或 str(d.quantize(...))
实际中,多数人忽略负数行为差异和浮点表示陷阱,直接用 math.floor(x * 100) / 100 就够用;但只要涉及钱,decimal 不是可选项,是必选项。