杰瑞科技汇

Java double四舍五入如何实现?

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

Java double四舍五入如何实现?-图1
(图片来源网络,侵删)

使用 Math.round() (最常用)

Math.round() 是 Java 中最直接、最常用的四舍五入方法,它返回一个 longint 类型的整数。

工作原理

  • 如果参数的小数部分 大于等于 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 是最佳选择。doublefloat 在计算机中是二进制浮点数,无法精确表示某些十进制小数(如 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 主要用于将数字格式化为字符串,但它也可以实现四舍五入的效果。

Java double四舍五入如何实现?-图2
(图片来源网络,侵删)

工作原理

通过设置格式化模式,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 的固有精度问题,在乘法和除法过程中可能会引入新的误差。
  • 代码复杂:不如 BigDecimalMath.round 直观和简洁。
  • 性能:性能通常不如内置方法。

总结与选择建议

方法 适用场景 优点 缺点
Math.round() double 四舍五入为最接近的 longint 简单、快速、内置。 返回整数类型,不保留小数。
BigDecimal 金融、财务、高精度计算 精度最高,可指定任意舍入模式。 代码稍多,对象创建有开销。
DecimalFormat 格式化数字用于显示(如日志、UI)。 方便格式化输出为字符串。 主要用于显示,不推荐用于计算。
手动实现 学习理解四舍五入原理。 有助于理解底层逻辑。 不推荐在生产代码中使用,有精度和性能问题。

核心建议:

  • 如果只是简单地将一个 double 变成最接近的整数,使用 Math.round()
  • 如果涉及金钱、财务或任何需要精确十进制计算的场景务必使用 BigDecimal,并用 String 构造它。
  • 如果只是想把数字格式化成字符串显示,使用 DecimalFormat
分享:
扫描分享到社交APP
上一篇
下一篇