DecimalFormat.format() 不显示两位小数是因为模式中使用了“#”而非“0”、setMinimumFractionDigits() 被错误设置,或 double 精度问题未预先舍入;正确做法是用"0.00"模式、避免干扰设置,并用BigDecimal或Math.round预处理数值。

DecimalFormat.format() 为什么有时不显示两位小数?
因为 DecimalFormat 默认使用“最少位数”策略,比如格式模式是 "0.00",但传入 1.0 或整数时,它仍可能输出 "1.00"——这看似符合,但若用的是 "#.##" 这类模式,就会直接变成 "1",小数位被完全省略。根本原因在于 # 表示“可选数字”,而 0 才表示“必须显示的数字占位符”。
正确设置模式字符串:用 0 而不是 # 控制小数位
要强制保留两位小数,模式中**小数点后必须用两个 0**,例如:
DecimalFormat df = new DecimalFormat("0.00");常见错误写法及问题:
-
"#.##"→ 输入5输出"5",不补零 -
"0.##"→ 输入7.0输出"7",第二位小数被忽略 -
"0.00"→ 输入4、4.0、4.1都输出"4.00"、"4.00"、"4.10"
注意 setMinimumFractionDigits() 的干扰
即使模式写对了,如果之前调用了 setMinimumFractionDigits(0)(或类似自定义设置),也可能覆盖模式行为。默认情况下 DecimalFormat 的 minimumFractionDigits 是 0,而 "0.00" 模式本身已隐含最小 2 位,所以通常无需额外设置。但如果你在复用同一个 DecimalFormat 实例,务必确认:
立即学习“Java免费学习笔记(深入)”;
- 没调用过
df.setMinimumFractionDigits(0)或df.setMaximumFractionDigits(1) - 没调用过
df.setDecimalSeparatorAlwaysShown(true)(这会让整数也显示.00,但一般不需要) - 最好每次用新实例,或重置:
df.applyPattern("0.00")
浮点精度问题会破坏预期结果
double 本身无法精确表示很多十进制小数(如 0.1 + 0.2 != 0.3),导致 format(0.1 + 0.2) 可能输出 "0.30000000000000004",再经 "0.00" 格式化后变成 "0.30"(看起来正常),但若计算误差更大(如累加误差),可能四舍五入出错。稳妥做法是:
- 业务中涉及金额等关键场景,改用
BigDecimal构造并指定RoundingMode.HALF_UP - 若坚持用
double,先做一次Math.round(value * 100.0) / 100.0再格式化(但要注意 double 除法仍有精度风险) - 直接用
BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP).toString()更可靠
真正容易被忽略的,是把 DecimalFormat 当作“四舍五入工具”来用——它只做格式化,不改变原始数值;该舍入的地方,得提前用 BigDecimal 或 Math.round 处理干净。


















