BigDecimal使用
解决浮点型运算时,出现结果失真的问题,比如0.1+0.2
—示例—
public class ErrorCase {public static void main(String[] args) {// 0.30000000000000004System.out.println(0.1 + 0.2);}
}
构造方法
- 把string转成BigDecimal
- 把double转BigDecimal还是有问题(不推荐使用)
BigDecimal.ValueOf
public class CorrectCase {public static void main(String[] args) {BigDecimal a = new BigDecimal(Double.toString(0.1));
// BigDecimal b = new BigDecimal(Double.toString(0.2));BigDecimal b = BigDecimal.valueOf(0.2); // 等价于上面这行代码// 有重写toStringSystem.out.println(a.add(b));// subtract, multiply, divide}
}
使用除法,注意添加精度,否则可能导致异常
public class ErrorCase2 {public static void main(String[] args) {BigDecimal i = BigDecimal.valueOf(0.1);BigDecimal j = BigDecimal.valueOf(0.3);// System.out.println(i.divide(j)); // error, 结果必须是准确的BigDecimal divide = i.divide(j, 2, RoundingMode.HALF_UP); // OK// 转为doubledouble v = divide.doubleValue();}
}
BigDecimal规范
BigDecimal不可变
这点特别关键,编码的时候可能会考虑塞入一个常量的0值会怎么样,认为会导致其被使用api的时候所修改,实际上并不会!
在Java中,BigDecimal是不可变的,这意味着一旦创建了BigDecimal对象,它的值就无法更改。因此,对BigDecimal对象的任何操作都会产生一个新的BigDecimal对象,而不会修改原始对象的值。
例如,对两个BigDecimal对象进行加法运算,会生成一个新的BigDecimal对象来存储结果,而不会修改原始对象的值。这种不可变性确保了BigDecimal对象的线程安全性和数据一致性。
以下是一个示例:
import java.math.BigDecimal;public class Main {public static void main(String[] args) {BigDecimal num1 = new BigDecimal("10");BigDecimal num2 = new BigDecimal("20");// 对两个BigDecimal对象进行加法运算BigDecimal result = num1.add(num2);System.out.println("Result: " + result);System.out.println("Original num1: " + num1); // 原始对象的值未改变System.out.println("Original num2: " + num2); // 原始对象的值未改变}
}
输出结果:
Result: 30
Original num1: 10
Original num2: 20
可以看到,即使对num1和num2进行了加法运算,它们的值仍然保持不变。这就是因为对BigDecimal对象的任何操作都会产生一个新的BigDecimal对象来存储结果,而不会修改原始对象的值。