BigDecimal
是 Java 中的一个类,用于表示任意精度的十进制数。它属于 java.math
包,并提供了高精度的浮点数运算。与基本数据类型的浮点数(如 float
和 double
)不同,BigDecimal
可以表示精确的小数,并且不会出现舍入误差。
主要的特点包括:
任意精度: BigDecimal
可以处理非常大或非常小的数字,而不会失去精度。这对于需要精确计算货币、税收等金融领域的数据非常重要。
不受二进制浮点数表示误差的影响: 由于二进制浮点数表示法的限制,基本数据类型的浮点数可能会导致舍入误差。BigDecimal
使用基于十进制的表示,避免了这种误差。
支持精确的算术运算: BigDecimal
提供了一系列的算术运算方法,如加法、减法、乘法和除法,这些运算可以保持高精度。
不可变性: BigDecimal
对象是不可变的,一旦创建,就不能被修改。这有助于确保线程安全性。
丰富的方法: BigDecimal
提供了许多用于比较、取整、取余等操作的方法。
以下是一个简单的示例,演示如何使用 BigDecimal
进行精确计算:
import java.math.BigDecimal;
public class BigDecimalExample {
public static void main(String[] args) {
BigDecimal num1 = new BigDecimal("10.5");
BigDecimal num2 = new BigDecimal("2.3");
// 加法
BigDecimal sum = num1.add(num2);
System.out.println("Sum: " + sum);
// 减法
BigDecimal difference = num1.subtract(num2);
System.out.println("Difference: " + difference);
// 乘法
BigDecimal product = num1.multiply(num2);
System.out.println("Product: " + product);
// 除法,指定保留小数位数和舍入模式
BigDecimal quotient = num1.divide(num2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println("Quotient: " + quotient);
}
}
在这个示例中,BigDecimal
被用于执行精确的加法、减法、乘法和除法操作,并且可以通过指定保留小数位数和舍入模式来控制除法的结果。
求和
BigDecimal sum = Arrays.stream(bdArray).reduce(BigDecimal.ZERO, (p, q) -> p.add(q));
BigDecimal sum = list.stream().map(Person::getWeight)
.reduce(BigDecimal.ZERO, BigDecimal::add);
自定义求和
BigDecimal sum = map.values().stream().reduce(BigDecimal.ZERO, Utility::addWeight);
import java.math.BigDecimal;
public class Utility {
public static BigDecimal addWeight(BigDecimal w1, BigDecimal w2) {
return w1.add(w2);
}
}
小数
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
public class BigDecimalSumUsingList {
public static void main(String[] args) {
Person p1 = new Person("AAA", new BigDecimal("45.23"));
Person p2 = new Person("BBB", new BigDecimal("55.43"));
Person p3 = new Person("CCC", new BigDecimal("65.21"));
Person p4 = new Person("DDD", new BigDecimal("35.73"));
List<Person> list = Arrays.asList(p1, p2, p3, p4);
BigDecimal sum = list.stream().map(Person::getWeight)
.reduce(BigDecimal.ZERO, BigDecimal::add);
System.out.println(sum);
sum = list.stream().map(p -> p.getWeight())
.reduce(BigDecimal.ZERO, (b1, b2) -> b1.add(b2));
System.out.println(sum);
sum = list.stream().map(Person::getWeight)
.reduce(BigDecimal.ZERO, Utility::addWeight);
System.out.println(sum);
}
}
BigDecimal求和
BigDecimal sum = products.stream()
.map(Product::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
先相乘再累加:
final BigDecimal mgmtPrmAmt = value.stream()
.map(product -> product.getMgmtPrmAmt().multiply(new BigDecimal(product.getSalQty())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
public BigDecimal add(BigDecimal value); //加
public BigDecimal subtract(BigDecimal value);//减
public BigDecimal multiply(BigDecimal value); //乘
public BigDecimal divide(BigDecimal value); //除
RoundingMode类型:
BigDecimal 的 divide 方法是用于执行除法运算的,其语法如下:
#语法
public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode)
#举例
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP);
其中,参数说明如下:
该方法返回一个 BigDecimal 对象,表示除法运算的结果。
import java.math.BigDecimal;
/**
* @author : qinyingjie
* @version : 2.2.0
* @date : 2022/10/5 12:27
*/
class Scratch {
public static void main(String[] args) {
//Java中BigDecimal取整方法
BigDecimal bd = new BigDecimal("12.1");
long l1 = bd.setScale(0, BigDecimal.ROUND_UP).longValue(); // 向上取整
long l2 = bd.setScale(0, BigDecimal.ROUND_DOWN).longValue(); // 向下取整
System.out.println(l1);
System.out.println(l2);
}
}
要将 a 除以 b,并将结果保留 2 位小数,可以使用如下代码:
BigDecimal a = new BigDecimal("10");
BigDecimal b = new BigDecimal("3");
BigDecimal result = a.divide(b, 2, RoundingMode.HALF_UP);
System.out.println(result);
在上述代码中,RoundingMode.HALF_UP 表示使用“四舍五入”方式将结果舍入到 2 位小数。
需要注意的是,如果除数为 0,则会抛出 ArithmeticException 异常。另外,如果计算结果超出了 BigDecimal 能表示的范围,则会抛出 ArithmeticException 异常。因此,在使用 BigDecimal 进行除法运算时,需要对这些异常进行适当的处理。
BigDecimal 如何判断是否大于 0、小于 0 和等于 0
if (number.compareTo(BigDecimal.ZERO) == 0) {
System.out.println("BigDecimal对象等于0");
} else {
System.out.println("BigDecimal对象不等于0");
}
取最大值并保留 4 位小数,使用的方法是一个数除以 1 等于它本身
max.setTotalSalQtyStoreRate(new BigDecimal(result.stream().mapToDouble(item -> Objects.nonNull(item.getTotalSalQtyStoreRate()) ? item.getTotalSalQtyStoreRate().doubleValue() : 0).max().getAsDouble())
.divide(new BigDecimal(1), 4, BigDecimal.ROUND_DOWN));
注意点:
BigDecimal divide(BigDecimal divisor, int scale, int roundingMode)
roundingMode 为四舍五入的规则模型,用常量 int 来表示