BigDecimal笔记
创建:
BigDecimal a = new BigDecimal(0.1); System.out.println(a);//0.1000000000000000055511151231257827021181583404541015625 System.out.println(a.doubleValue());//0.1
我们可以看到用构建方法创建时如果是数值会有精度问题,但在转换为double时又正常了;那么在操作的时候精度是否正常呢?
BigDecimal b = BigDecimal.valueOf(0.1); System.out.println(b);//0.1 System.out.println(a.compareTo(b));//1
如果使用valueOf()方法创建就不会出现精度问题,并且我使用compareTo()方法比较了大小,发现a比b大,所以a在操作时精度问题是存在的,所以我们尽量使用第二种方法创建。
BigDecimal c = new BigDecimal("0.1"); System.out.println(c);//0.1
如果是在构建时传入的是字符串,就不会出现精度问题。事实上第二种创建方法内部其实是调用了第三种创建方法的return new BigDecimal(Double.toString(val));把数值转换成字符串后再创建的。
常用方法:
加减乘除,这里要提一下,加减乘除都是有返回值的,返回结果的BigDecimal对象,而不是改变原有的操作数。
BigDecimal x; x = b.add(c);//加 System.out.println(x);//0.2 x = b.subtract(c);//减 System.out.println(x);//0.0 x = b.multiply(c);//乘 System.out.println(x);//0.01 x = b.divide(c);//除 System.out.println(x);//1 x = b.divide(BigDecimal.valueOf(0.022),2,BigDecimal.ROUND_HALF_UP);//除,保留2位小数,四舍五入 System.out.println(x);//4.55
取舍规则:
BigDecimal.ROUND_UP 绝对值向上取整;已过期,替代:RoundingMode.UP
BigDecimal y = BigDecimal.valueOf(0.1111111).setScale(2,BigDecimal.ROUND_UP); System.out.println(y);//0.12 y = BigDecimal.valueOf(-0.1111111).setScale(2,BigDecimal.ROUND_UP); System.out.println(y);//-0.12
BigDecimal.ROUND_DOWN 绝对值向下取整;已过期,替代:RoundingMode.DOWN
BigDecimal y = BigDecimal.valueOf(0.1111111).setScale(2,BigDecimal.ROUND_DOWN); System.out.println(y);//0.11 y = BigDecimal.valueOf(-0.1111111).setScale(2,BigDecimal.ROUND_DOWN); System.out.println(y);//-0.11
BigDecimal.ROUND_CEILING 向上取整;已过期,替代:RoundingMode.CEILING
BigDecimal y = BigDecimal.valueOf(0.1111111).setScale(2,BigDecimal.ROUND_CEILING); System.out.println(y);//0.12 y = BigDecimal.valueOf(-0.1111111).setScale(2,BigDecimal.ROUND_CEILING); System.out.println(y);//-0.11
BigDecimal.ROUND_FLOOR 向下取整;已过期,替代:RoundingMode.FLOOR
BigDecimal y = BigDecimal.valueOf(0.1111111).setScale(2,BigDecimal.ROUND_FLOOR); System.out.println(y);//0.11 y = BigDecimal.valueOf(-0.1111111).setScale(2,BigDecimal.ROUND_FLOOR); System.out.println(y);//-0.12
BigDecimal.ROUND_HALF_UP 四舍五入;已过期,替代:RoundingMode.HALF_UP
BigDecimal y = BigDecimal.valueOf(0.444444).setScale(2,BigDecimal.ROUND_HALF_UP); System.out.println(y);//0.44 y = BigDecimal.valueOf(0.555555).setScale(2,BigDecimal.ROUND_HALF_UP); System.out.println(y);//0.56
BigDecimal.ROUND_HALF_DOWN 这个比较特殊,我称之为5舍5+入,看一下例子就懂了,这里看的不只是保留位下一位的数值,而是保留位后面的所有位数值,因为0.0050000001大于0.005,所以进,而小于或等于0.005则舍弃;已过期,替代:RoundingMode.HALF_DOWN
BigDecimal y = BigDecimal.valueOf(0.555).setScale(2,BigDecimal.ROUND_HALF_DOWN); System.out.println(y);//0.55 y = BigDecimal.valueOf(0.5550000001).setScale(2,BigDecimal.ROUND_HALF_DOWN); System.out.println(y);//0.56
BigDecimal.ROUND_HALF_EVEN 银行家算法,四舍六入,如果为5,看看后面还有没有数,有就进位,没有则看前面一位,如果为奇数则进位,如果为偶数则舍弃;已过期,替代:RoundingMode.HALF_EVEN
BigDecimal y = BigDecimal.valueOf(0.554).setScale(2,BigDecimal.ROUND_HALF_EVEN); System.out.println(y);//0.55 y = BigDecimal.valueOf(0.556).setScale(2,BigDecimal.ROUND_HALF_EVEN); System.out.println(y);//0.56 y = BigDecimal.valueOf(0.555001).setScale(2,BigDecimal.ROUND_HALF_EVEN); System.out.println(y);//0.56 y = BigDecimal.valueOf(0.515).setScale(2,BigDecimal.ROUND_HALF_EVEN); System.out.println(y);//0.52 y = BigDecimal.valueOf(0.525).setScale(2,BigDecimal.ROUND_HALF_EVEN); System.out.println(y);//0.52
BigDecimal.ROUND_UNNECESSARY 用于断言请求的操作具有精确结果,因此不发生舍入,说人话就是,在取舍之前我就知道不需要取舍。如果数值真的需要取舍才能达到限制的精度,就抛异常。已过期,替代:RoundingMode.UNNECESSARY
BigDecimal y = BigDecimal.valueOf(1.00).setScale(0,BigDecimal.ROUND_UNNECESSARY); System.out.println(y);//1 y = BigDecimal.valueOf(1).divide(BigDecimal.valueOf(100),2,BigDecimal.ROUND_UNNECESSARY); System.out.println(y);//0.01 y = BigDecimal.valueOf(1).divide(BigDecimal.valueOf(1000),2,BigDecimal.ROUND_UNNECESSARY);//抛出java.lang.ArithmeticException
比较大小:compareTo()
BigDecimal d = BigDecimal.valueOf(0.1); BigDecimal e = BigDecimal.valueOf(0.1); BigDecimal f = BigDecimal.valueOf(0.09999999); BigDecimal g = BigDecimal.valueOf(0.10000001); int n = d.compareTo(e); System.out.println(n);//0 d等于e n = d.compareTo(f); System.out.println(n);//1 d大于f n = d.compareTo(g); System.out.println(n);//-1 d小于g