网上讲BigDecimal的内容很多了,就不再做重复工作了,现就根据自己的使用体会,以实用为目的将自己的学习笔记整理一下。
想要回答以下问题:
1.为什么要使用BigDecimal;
2.BigDecimal的基本用法;
3.使用BigDecimal时,需要注意的问题。
就直接以我学习过程中的测试代码为例,进行说明。
import java.math.BigDecimal;
public class TestBigDecimal {
public static void main(String[] args) {
testDouble();
testBigDecimalConstructor();
testArithmetic();
testScale();
testImmutable();
testBug();
summary();
}
private static void testDouble() {
// 浮点数是不精确的
// 请观察以下示例:
System.out.println(0.2 + 0.1);
System.out.println(0.3 - 0.1);
System.out.println(0.2 * 0.1);
System.out.println(0.3 / 0.1);
// 千万不要对浮点数进行比较大小,因为浮点数是不精确的
System.out.println(0.2 + 0.1 == 0.3);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void testBigDecimalConstructor() {
// BigDecimal的构造方法有多个,为了避免一个问题,推荐使用BigDecimal(String param)这个
// 请观察以下示例:
BigDecimal bd1 = new BigDecimal(1);
BigDecimal bd2 = new BigDecimal(1.1);
BigDecimal bd3 = new BigDecimal("1.1");
System.out.println("bd1 = " + bd1);
System.out.println("bd2 = " + bd2);
System.out.println("bd3 = " + bd3);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void testArithmetic() {
// BigDecimal的基本用法就是进行四则运算,即加减乘除
// 请观察以下示例:
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("2.0");
System.out.println("bd1 + bd2 = " + bd1.add(bd2));
System.out.println("bd1 - bd2 = " + bd1.subtract(bd2));
System.out.println("bd1 * bd2 = " + bd1.multiply(bd2));
System.out.println("bd1 / bd2 = " + bd1.divide(bd2));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void testScale() {
// 使用BigDecimal时,通常需要为结果指定精度和取整方式
// 精度,通俗的讲就是保留几位小数
// 取整方式,最常用的就是四舍五入
// 请观察以下示例:
BigDecimal bd1 = new BigDecimal("1.123");
BigDecimal bd2 = new BigDecimal("2.246");
System.out.println("before set scale : bd1 + bd2 = " + bd1.add(bd2));
System.out.println("After set scale : bd1 + bd2 = " + bd1.add(bd2).setScale(2,BigDecimal.ROUND_HALF_UP));
System.out.println("before set scale : bd1 - bd2 = " + bd1.subtract(bd2));
System.out.println("After set scale : bd1 - bd2 = " + bd1.subtract(bd2).setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println("before set scale : bd1 * bd2 = " + bd1.multiply(bd2));
System.out.println("After set scale : bd1 * bd2 = " + bd1.multiply(bd2).setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println("before set scale : bd1 / bd2 = " + bd1.divide(bd2));
System.out.println("After set scale : bd1 / bd2 = " + bd1.divide(bd2).setScale(2, BigDecimal.ROUND_HALF_UP));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void testImmutable() {
// BigDecimal是不可变类,所以BigDecimal对象进行运算之后,并不会改变其值
// BigDecial的运算基本都是返回一个新的BigDecimal对象
// 请观察一下示例:
BigDecimal bd1 = new BigDecimal("1.0");
BigDecimal bd2 = new BigDecimal("2.0");
bd1.add(bd2);
System.out.println("bd1 = " + bd1);
bd1.subtract(bd2);
System.out.println("bd1 = " + bd1);
bd1.multiply(bd2);
System.out.println("bd1 = " + bd1);
bd1.divide(bd2);
System.out.println("bd1 = " + bd1);
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void testBug() {
// 在使用BigDecimal时,需要注意两个常见bug
// 请观察以下示例:
BigDecimal bd1 = new BigDecimal("1.11");
BigDecimal bd2 = new BigDecimal("3.33");
// 设置的scale小于实际scale时,导致存在舍入误差,所以下边这行会报异常
//System.out.println("bd1 + bd2 = " + bd1.add(bd2).setScale(1));
// 正确做法,当设置scale时,请指定取整模式
System.out.println("bd1 + bd2 = " + bd1.add(bd2).setScale(1,BigDecimal.ROUND_HALF_UP));
// 进行除法运算时,一定要小心掉坑。当遇到除不尽的情况时,下边这行代码会报异常
//System.out.println("After set scale : bd1 / bd2 = " + bd1.divide(bd2));
// 为了避免上述异常,应当采用下边的使用方式。设置保留几位小数,以及取整方式。这种方式更安全!
System.out.println("After set scale : bd1 / bd2 = " + bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP));
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>我是分割线<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");
}
private static void summary() {
StringBuilder summary = new StringBuilder();
summary.append("1.在实际工作中,基本上所有的数值计算都是要求精确计算的,由于float或double是不精确的,因此需要使用BigDecimal进行精确计算;\n");
summary.append("2.建议使用BigDecimal(String)构造器;\n");
summary.append("3.BigDecimal最常用的用法是进行四则运算,除此之外还有进行其他数值运算的方法,用到的时候再去查;\n");
summary.append("4.BigDecimal最常用的取整方式就是四舍五入,Round_HALF_UP;\n");
summary.append("5.BigDecimal是一个不可变类,方法返回的都是一个新的BigDecimal对象;\n");
summary.append("6.BigDecimal进行除法运算时,一定要注意处理除不尽的情况,避免因除不尽报异常。\n");
System.out.println(summary);
}
}