2024-07-22
你的温柔只为我一个,我的坚强只为你一人。 --- 《作者本人》 · 忆
BigDecimal
在Java中,BigDecimal
是一个用于处理高精度计算的类,位于 java.math
包中。它提供对浮点数的任意精度的表示和运算,适用于对精度要求较高的场景,例如财务计算和科学计算。与原生的 float
和 double
类型相比,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
方法接受两个参数:
- 初始值:
BigDecimal.ZERO
,表示累加的起始值。 - 累加函数:
BigDecimal::add
,表示累加操作。
更详细的说明
-
创建一个
List<BigDecimal>
:List<BigDecimal> numbers = Arrays.asList(
new BigDecimal("10.5"),
new BigDecimal("20.75"),
new BigDecimal("30.25"),
new BigDecimal("40.0")
);这里我们创建了一个包含几个
BigDecimal
值的列表。 -
使用
stream
方法将List
转换为Stream<BigDecimal>
:numbers.stream()
通过
stream
方法,我们将List
转换为了一个流,以便进行后续的操作。 -
使用
reduce
方法求和:.reduce(BigDecimal.ZERO, BigDecimal::add)
reduce
方法将流中的所有元素按照指定的累加函数进行累加,BigDecimal.ZERO
是累加的初始值,BigDecimal::add
是累加函数。 -
输出结果:
System.out.println("Sum: " + sum);
以上代码将输出:
Sum: 101.50
这种方法简洁高效,利用了 Stream
API 的优势,可以很好地处理集合中的各种聚合操作。