
本文介绍两种可靠方式——使用 `decimalformat` 配合 `roundingmode.down`,或通过 `bigdecimal` 的 `setscale()` 方法——实现对 double 值的小数位**截断(truncation)而非四舍五入**,确保 19.867 精确变为 19.86。
在 Java 中,printf("%1.2f", x) 或 String.format("%.2f", x) 默认采用四舍五入(HALF_UP),因此 19.867 会被格式化为 "19.87"。若需严格截断(即向下舍去多余小数位,不进位),必须显式指定截断语义。以下是两种推荐方案:
✅ 方案一:使用 DecimalFormat + RoundingMode.DOWN
import java.text.DecimalFormat;
import java.math.RoundingMode;
double number1 = 19.867;
DecimalFormat df = new DecimalFormat("#.##");
df.setRoundingMode(RoundingMode.DOWN); // 关键:强制向下截断
System.out.println(df.format(number1)); // 输出:19.86⚠️ 注意:
- 模式 "#.##" 支持省略末尾零(如 19.80 → "19.8"),若需固定两位(如始终显示 19.80),应改用 "0.00";
- RoundingMode.DOWN 对正数等价于“向零截断”,但对负数(如 -19.867)也会截为 -19.86(即绝对值变小),符合多数业务场景预期。
✅ 方案二:使用 BigDecimal(更精确、推荐用于金融计算)
import java.math.BigDecimal;
import java.math.RoundingMode;
double number1 = 19.867;
BigDecimal bd = new BigDecimal(Double.toString(number1)) // 推荐:用字符串构造,避免 double 二进制精度误差
.setScale(2, RoundingMode.DOWN);
System.out.println(bd.doubleValue()); // 输出:19.86
// 或直接输出字符串:System.out.println(bd); // 输出:19.86(无精度丢失)? 关键提示:
- 务必使用 new BigDecimal(Double.toString(x)) 而非 new BigDecimal(x),因为 double 字面量本身可能存在二进制表示误差(如 0.1 实际存储为 0.10000000000000000555...),直接构造会导致意外结果;
- BigDecimal 返回的是精确的十进制数值,doubleValue() 仅在需转回 double 时调用——若后续仍需高精度运算,建议全程保留 BigDecimal 类型。
? 总结
| 场景 | 推荐方案 | 说明 |
|---|---|---|
| 快速格式化输出(如日志、控制台) | DecimalFormat + RoundingMode.DOWN | 简洁高效,注意模式与舍入模式搭配 |
| 金额、科学计算等高精度需求 | BigDecimal + setScale(2, RoundingMode.DOWN) | 安全可靠,规避浮点误差,强烈推荐 |
无论选择哪种方式,核心都是显式指定 RoundingMode.DOWN ——这是实现“截断”而非“四舍五入”的关键。切勿依赖默认行为。
立即学习“Java免费学习笔记(深入)”;










