跳到主要内容

2024-07-22

一言

你的温柔只为我一个,我的坚强只为你一人。 --- 《作者本人》 · 忆


BigDecimal

在Java中,BigDecimal 是一个用于处理高精度计算的类,位于 java.math 包中。它提供对浮点数的任意精度的表示和运算,适用于对精度要求较高的场景,例如财务计算和科学计算。与原生的 floatdouble 类型相比,BigDecimal 能够避免由于二进制浮点数表示方式导致的精度损失问题。

以下是 BigDecimal 的一些关键特性和常见用法:

1. 创建 BigDecimal 对象

可以通过字符串、整数、浮点数等多种方式创建 BigDecimal 对象,但推荐使用字符串构造方法以避免精度问题。

import java.math.BigDecimal;

BigDecimal fromString = new BigDecimal("123.456");
BigDecimal fromInt = new BigDecimal(123);
BigDecimal fromDouble = new BigDecimal(123.456); // 不推荐,可能会引入精度问题

2. 常用方法

  • 加法运算
BigDecimal a = new BigDecimal("10.5");
BigDecimal b = new BigDecimal("2.3");
BigDecimal result = a.add(b); // result: 12.8
  • 减法运算
BigDecimal result = a.subtract(b); // result: 8.2
  • 乘法运算
BigDecimal result = a.multiply(b); // result: 24.15
  • 除法运算

除法时需要指定精度和舍入模式,以避免精度问题。

BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP); // result: 4.57
  • 比较
int comparison = a.compareTo(b); // 返回-1(小于),0(等于),1(大于)
  • 取整
BigDecimal result = a.setScale(0, RoundingMode.HALF_UP); // result: 11

3. 舍入模式

BigDecimal 提供多种舍入模式,例如:

  • RoundingMode.UP:向远离零的方向舍入。
  • RoundingMode.DOWN:向接近零的方向舍入。
  • RoundingMode.CEILING:向正无穷方向舍入。
  • RoundingMode.FLOOR:向负无穷方向舍入。
  • RoundingMode.HALF_UP:四舍五入。
  • RoundingMode.HALF_DOWN:五舍六入。
  • RoundingMode.HALF_EVEN:银行家舍入法。

示例代码

以下是一个使用 BigDecimal 进行基本计算的示例:

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimalExample {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("123.456");
BigDecimal b = new BigDecimal("10.123");

BigDecimal sum = a.add(b);
BigDecimal difference = a.subtract(b);
BigDecimal product = a.multiply(b);
BigDecimal quotient = a.divide(b, 2, RoundingMode.HALF_UP);

System.out.println("Sum: " + sum);
System.out.println("Difference: " + difference);
System.out.println("Product: " + product);
System.out.println("Quotient: " + quotient);
}
}

在高精度计算中,BigDecimal 是一个非常强大的工具,但需要注意的是,BigDecimal 的运算相比于原生的浮点数运算可能会更慢,因此在性能敏感的场景下需要权衡使用。

Stream.reduce

你可以使用 Java 中的 Stream API 来求和一个 List<BigDecimal>Stream API 提供了一个方便的方法来对集合进行各种操作,包括聚合操作,如求和。

以下是一个简单的例子,展示如何使用 Stream API 来对一个 List<BigDecimal> 求和:

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;

public class BigDecimalSumExample {
public static void main(String[] args) {
List<BigDecimal> numbers = Arrays.asList(
new BigDecimal("10.5"),
new BigDecimal("20.75"),
new BigDecimal("30.25"),
new BigDecimal("40.0")
);

BigDecimal sum = numbers.stream()
.reduce(BigDecimal.ZERO, BigDecimal::add);

System.out.println("Sum: " + sum);
}
}

在这个例子中,我们使用了 reduce 方法来累加 List<BigDecimal> 中的所有元素。reduce 方法接受两个参数:

  1. 初始值BigDecimal.ZERO,表示累加的起始值。
  2. 累加函数BigDecimal::add,表示累加操作。

更详细的说明

  1. 创建一个 List<BigDecimal>

    List<BigDecimal> numbers = Arrays.asList(
    new BigDecimal("10.5"),
    new BigDecimal("20.75"),
    new BigDecimal("30.25"),
    new BigDecimal("40.0")
    );

    这里我们创建了一个包含几个 BigDecimal 值的列表。

  2. 使用 stream 方法将 List 转换为 Stream<BigDecimal>

    numbers.stream()

    通过 stream 方法,我们将 List 转换为了一个流,以便进行后续的操作。

  3. 使用 reduce 方法求和

    .reduce(BigDecimal.ZERO, BigDecimal::add)

    reduce 方法将流中的所有元素按照指定的累加函数进行累加,BigDecimal.ZERO 是累加的初始值,BigDecimal::add 是累加函数。

  4. 输出结果

    System.out.println("Sum: " + sum);

以上代码将输出:

Sum: 101.50

这种方法简洁高效,利用了 Stream API 的优势,可以很好地处理集合中的各种聚合操作。