在 Java 中,将 double 类型保留两位小数有多种方法,每种方法都有其适用场景,选择哪种取决于你的具体需求(用于显示、用于计算、还是用于格式化输出)。

下面我将介绍几种最常用和最推荐的方法,并附上代码示例。
使用 String.format() 或 System.out.printf() (推荐用于显示和输出)
这是最简单、最直观的方法,主要用于将数字格式化为字符串以便显示,它不会改变原始 double 变量的值,只是生成一个格式化后的字符串。
String.format()
这个方法会返回一个格式化后的字符串,你可以将它赋值给一个 String 变量。
public class DoubleFormatter {
public static void main(String[] args) {
double number = 123.456789;
// 使用 String.format() 格式化为两位小数
String formattedNumber = String.format("%.2f", number);
System.out.println("原始数字: " + number); // 输出: 原始数字: 123.456789
System.out.println("格式化后: " + formattedNumber); // 输出: 格式化后: 123.46
}
}
格式说明:

"%.2f"是格式化字符串。- 表示格式说明符的开始。
.2表示保留两位小数。f表示这是一个浮点数(float 或 double)。
System.out.printf()
这个方法直接将格式化后的输出到控制台,更像是 C 语言中的 printf。
public class DoubleFormatter {
public static void main(String[] args) {
double number = 123.456789;
// 使用 System.out.printf() 直接格式化输出
System.out.printf("格式化输出: %.2f%n", number); // 输出: 格式化输出: 123.46
}
}
注意:
printf默认会进行“四舍五入”。%n是一个与平台无关的换行符,推荐使用。
使用 DecimalFormat (推荐用于本地化和复杂的格式化)
java.text.DecimalFormat 是一个功能更强大的格式化工具,尤其适用于需要本地化(如不同地区的千位分隔符、小数点符号不同)的场景。
import java.text.DecimalFormat;
public class DoubleFormatter {
public static void main(String[] args) {
double number = 1234567.895;
// 1. 创建 DecimalFormat 对象,并指定模式
// "###,###.##" 表示:整数部分每三位用逗号分隔,保留两位小数
DecimalFormat df = new DecimalFormat("###,###.##");
// 2. 使用 format() 方法进行格式化
String formattedNumber = df.format(number);
System.out.println("原始数字: " + number);
System.out.println("格式化后: " + formattedNumber); // 输出: 格式化后: 1,234,567.90
}
}
格式说明:

- 数字,如果不存在则不显示。
0:数字,如果不存在则显示为0。- 千位分隔符。
- 小数点分隔符。
使用 BigDecimal (推荐用于精确的数学计算)
如果你需要进行财务计算或任何对精度要求很高的计算,强烈推荐使用 BigDecimal,直接使用 double 或 float 进行计算可能会因为二进制浮点数精度问题导致错误。
BigDecimal 可以精确地控制舍入模式。
import java.math.BigDecimal;
import java.math.RoundingMode;
public class DoubleFormatter {
public static void main(String[] args) {
double number = 123.456789;
// 1. 将 double 转换为 BigDecimal
// 注意:为了避免 double 本身的精度问题,最好用字符串构造 BigDecimal
// new BigDecimal("123.456789");
BigDecimal bd = new BigDecimal(number);
// 2. 设置保留两位小数,并指定舍入模式
// RoundingMode.HALF_UP 表示四舍五入
BigDecimal roundedNumber = bd.setScale(2, RoundingMode.HALF_UP);
// 3. 如果需要字符串,可以使用 toPlainString() 或 toString()
String formattedNumber = roundedNumber.toPlainString();
System.out.println("原始数字: " + number);
System.out.println("格式化后: " + formattedNumber); // 输出: 格式化后: 123.46
}
}
为什么用 BigDecimal?
// 一个经典的 double 计算错误示例
System.out.println(0.1 + 0.2); // 输出可能不是 0.3,而是 0.30000000000000004
// 使用 BigDecimal 可以避免这个问题
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal sum = a.add(b);
System.out.println(sum); // 输出: 0.3
使用 Math.round() (不推荐用于最终显示,仅用于计算)
这个方法会进行四舍五入,并返回一个 long 或 int 类型的结果,它不是用来格式化显示的,而是用来得到一个整数近似值。
public class DoubleFormatter {
public static void main(String[] args) {
double number = 123.456;
// Math.round() 会四舍五入到最接近的整数
// 注意:要先乘以 100,再除以 100.0,否则会丢失精度
double roundedNumber = Math.round(number * 100.0) / 100.0;
System.out.println("原始数字: " + number);
System.out.println("处理后: " + roundedNumber); // 输出: 处理后: 123.46
}
}
为什么不推荐?
- 精度问题:
double本身就有精度限制,这种乘除运算可能会引入新的误差。 - 显示问题:结果仍然是
double类型,当你直接System.out.println()时,它可能会显示更多的小数位(45999999999998)。 - 适用场景:仅在中间计算步骤中需要一个近似值时使用。
总结与最佳实践
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
String.format() |
字符串格式化输出、显示 | 简单、快捷、易读 | 不改变原始变量值,不用于计算 |
DecimalFormat |
复杂格式化(如千位分隔符)、本地化 | 功能强大,格式灵活 | 比 String.format() 稍显繁琐 |
BigDecimal |
高精度计算、财务计算 | 精度最高,可控的舍入模式 | 代码稍多,对象创建有开销 |
Math.round() |
中间计算步骤的整数近似 | 直接返回数值 | 有精度风险,不适合最终显示 |
如何选择?
-
如果只是为了在屏幕上打印或显示给用户看:
- 首选
String.format("%.2f", value)。
- 首选
-
如果需要进行精确的数学运算(比如涉及钱的计算):
- 必须使用
BigDecimal。永远不要用double或float来表示金额!
- 必须使用
-
如果需要复杂的格式(如
1,234.56这种带千位分隔符的):- 使用
DecimalFormat。
- 使用
-
尽量避免使用
Math.round()来保留小数位,除非你非常清楚自己在做什么。
