在 Java 中,对 double 类型进行四舍五入有几种常见的方法,每种方法都有其适用场景和注意事项,下面我将详细介绍这些方法,并提供代码示例。

(图片来源网络,侵删)
使用 Math.round() (最常用)
Math.round() 是 Java 中最直接、最常用的四舍五入方法,它返回一个 long 或 int 类型的整数。
工作原理
- 如果参数的小数部分 大于等于 0.5,则向“正无穷”方向舍入(向上取整)。
- 如果参数的小数部分 小于 0.5,则向“零”方向舍入(向下取整)。
方法签名
long round(double a): 返回最接近的long类型值。int round(float a): 返回最接近的int类型值。
示例代码
public class MathRoundExample {
public static void main(String[] args) {
double number1 = 3.49;
double number2 = 3.50;
double number3 = -3.49;
double number4 = -3.50;
// Math.round() 返回 long 类型
long result1 = Math.round(number1); // 3
long result2 = Math.round(number2); // 4
long result3 = Math.round(number3); // -3
long result4 = Math.round(number4); // -4
System.out.println("Math.round(3.49) = " + result1);
System.out.println("Math.round(3.50) = " + result2);
System.out.println("Math.round(-3.49) = " + result3);
System.out.println("Math.round(-3.50) = " + result4);
// 如果想得到 int 类型,可以强制转换
int intResult = (int) Math.round(3.49);
System.out.println("(int) Math.round(3.49) = " + intResult);
}
}
输出
Math.round(3.49) = 3
Math.round(3.50) = 4
Math.round(-3.49) = -3
Math.round(-3.50) = -4
(int) Math.round(3.49) = 3
注意事项
- 返回类型:
Math.round(double)返回的是long,而不是double,如果你需要保留小数位数,或者结果是double类型,这个方法不适用。 - 负数处理:对于负数,
Math.round()的行为符合标准的四舍五入规则(-3.5 会舍入到 -4)。
使用 BigDecimal (最精确,推荐用于金融计算)
当你需要精确的十进制运算,特别是处理金钱、财务等场景时,使用 BigDecimal 是最佳选择。double 和 float 在计算机中是二进制浮点数,无法精确表示某些十进制小数(如 0.1),这会导致精度丢失。
工作原理
BigDecimal 提供了 setScale() 方法,可以指定保留的小数位数和舍入模式。
示例代码
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalExample {
public static void main(String[] args) {
double number = 123.4567;
// 1. 将 double 转换为 BigDecimal (注意:直接使用 double 构造仍有精度问题)
// 更推荐的方式是使用 String 构造
BigDecimal bd = new BigDecimal(String.valueOf(number));
// 2. 设置保留两位小数,并使用四舍五入模式
BigDecimal roundedBd = bd.setScale(2, RoundingMode.HALF_UP);
// 3. 转换回 double
double result = roundedBd.doubleValue();
System.out.println("原始数字: " + number);
System.out.println("四舍五入后 (2位小数): " + result); // 输出 123.46
// 另一个例子
BigDecimal bd2 = new BigDecimal("100.125");
BigDecimal roundedBd2 = bd2.setScale(2, RoundingMode.HALF_UP);
System.out.println("四舍五入后 (2位小数): " + roundedBd2); // 输出 100.13
}
}
输出
原始数字: 123.4567
四舍五入后 (2位小数): 123.46
四舍五入后 (2位小数): 100.13
为什么推荐使用 String 构造 BigDecimal?
// 错误示范:直接使用 double 构造 BigDecimal
double d = 0.1;
BigDecimal badBd = new BigDecimal(d); // 内部 d 的实际值可能不是精确的 0.1
System.out.println(badBd); // 可能输出 0.1000000000000000055511151231257827021181583404541015625
// 正确示范:使用 String 构造
BigDecimal goodBd = new BigDecimal("0.1");
System.out.println(goodBd); // 输出 0.1
RoundingMode 常用枚举
RoundingMode.HALF_UP: 标准的四舍五入(这是我们通常说的四舍五入)。RoundingMode.HALF_DOWN: “五舍六入”(.5 时向零方向舍入)。RoundingMode.HALF_EVEN: 银行家舍入法(.5 时舍入到最接近的偶数,这是统计和金融计算中最常用的舍入方式,可以减少累积误差)。RoundingMode.UP: 远离零方向舍入(正数向上,负数向下)。RoundingMode.DOWN: 向零方向舍入(正数向下,负数向上)。
使用 DecimalFormat (用于格式化输出)
DecimalFormat 主要用于将数字格式化为字符串,但它也可以实现四舍五入的效果。

(图片来源网络,侵删)
工作原理
通过设置格式化模式,DecimalFormat 会在格式化过程中自动进行舍入。
示例代码
import java.text.DecimalFormat;
public class DecimalFormatExample {
public static void main(String[] args) {
double number = 123.4567;
// 创建一个模式,#.## 表示保留两位小数
DecimalFormat df = new DecimalFormat("#.##");
// 格式化数字,结果是一个 String
String formattedString = df.format(number);
System.out.println("格式化后的字符串: " + formattedString); // 输出 123.46
// 如果需要得到 double,可以再转换回去
double result = Double.parseDouble(formattedString);
System.out.println("转换回 double: " + result);
}
}
输出
格式化后的字符串: 123.46
转换回 double: 123.46
注意事项
DecimalFormat主要用于显示和格式化,而不是中间计算,如果你的计算过程需要高精度,应该优先使用BigDecimal。- 它的舍入模式默认也是
RoundingMode.HALF_EVEN(银行家舍入法)。
手动实现 (不推荐,但有助于理解原理)
你可以通过乘法、取整、再除法的方式手动实现四舍五入。
示例代码
public class ManualRounding {
public static void main(String[] args) {
double number = 123.456;
int decimalPlaces = 2;
// 1. 乘以 10 的 n 次方
double factor = Math.pow(10, decimalPlaces);
double temp = number * factor; // 12345.6
// 2. 使用 Math.round 进行四舍五入
double roundedTemp = Math.round(temp); // 12346.0
// 3. 除以 10 的 n 次方
double result = roundedTemp / factor; // 123.46
System.out.println("手动四舍五入结果: " + result);
}
}
输出
手动四舍五入结果: 123.46
为什么不推荐?
- 精度问题:由于
double的固有精度问题,在乘法和除法过程中可能会引入新的误差。 - 代码复杂:不如
BigDecimal或Math.round直观和简洁。 - 性能:性能通常不如内置方法。
总结与选择建议
| 方法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
Math.round() |
将 double 四舍五入为最接近的 long 或 int。 |
简单、快速、内置。 | 返回整数类型,不保留小数。 |
BigDecimal |
金融、财务、高精度计算。 | 精度最高,可指定任意舍入模式。 | 代码稍多,对象创建有开销。 |
DecimalFormat |
格式化数字用于显示(如日志、UI)。 | 方便格式化输出为字符串。 | 主要用于显示,不推荐用于计算。 |
| 手动实现 | 学习理解四舍五入原理。 | 有助于理解底层逻辑。 | 不推荐在生产代码中使用,有精度和性能问题。 |
核心建议:
- 如果只是简单地将一个
double变成最接近的整数,使用Math.round()。 - 如果涉及金钱、财务或任何需要精确十进制计算的场景,务必使用
BigDecimal,并用String构造它。 - 如果只是想把数字格式化成字符串显示,使用
DecimalFormat。
