BigDecimal使用

使用场景

BigDecimal用于表示精确的小数,常用于财务计算;

比较BigDecimal的值是否相等,必须使用compareTo()而不能使用equals()

特征

  • BigDecimal是不可变类,每次修改、计算返回的是新对象
  • BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数

加减乘除

  • 加法:add()函数
  • 减法:subtract()函数
  • 乘法:multiply()函数
  • 除法:divide()函数
  • 绝对值:abs()函数

【注意】!

  • 不要使用double构造BigDecimal,会丢失精度,要用String构造

    因为此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入 到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

  • 如果一定要通过double构造对象,可以先Double.toString(double)得到String,再用String去构造对象

其他方法

scale()

返回小数位数

BigDecimal d1 = new BigDecimal("123.45");
BigDecimal d2 = new BigDecimal("123.4500");
BigDecimal d3 = new BigDecimal("1234500");
System.out.println(d1.scale()); // 2,两位小数
System.out.println(d2.scale()); // 4
System.out.println(d3.scale()); // 0

stripTrailingZeros()

​ 可以将一个BigDecimal格式化为一个相等的,但去掉了末尾0的BigDecimal,如果一个BigDecimalscale()返回负数,例如,-2,表示这个数是个整数,并且末尾有2个0。

BigDecimal d1 = new BigDecimal("123.4500");
BigDecimal d2 = d1.stripTrailingZeros();
System.out.println(d1.scale()); // 4
System.out.println(d2.scale()); // 2,因为去掉了00

BigDecimal d3 = new BigDecimal("1234500");
BigDecimal d4 = d3.stripTrailingZeros();
System.out.println(d3.scale()); // 0
System.out.println(d4.scale()); // -2

setScale()

可以对一个BigDecimal设置它的scale,如果精度比原始值低,那么按照指定的方法进行四舍五入或者直接截断

		BigDecimal d1 = new BigDecimal("123.456789");
        BigDecimal d2 = d1.setScale(4, RoundingMode.HALF_UP); // 四舍五入,123.4568
        BigDecimal d3 = d1.setScale(4, RoundingMode.DOWN); // 直接截断,123.4567
        System.out.println(d2);
        System.out.println(d3);

divide(d2, 10, RoundingMode.HALF_UP)

BigDecimal做加、减、乘时,精度不会丢失,但是做除法时,存在无法除尽的情况,这时,就必须指定精度以及如何进行截断

BigDecimal d1 = new BigDecimal("123.456");
BigDecimal d2 = new BigDecimal("23.456789");
BigDecimal d3 = d1.divide(d2, 10, RoundingMode.HALF_UP); // 保留10位小数并四舍五入
BigDecimal d4 = d1.divide(d2); // 报错:ArithmeticException,因为除不尽

divideAndRemainder(BigDecimal m)

可以对BigDecimal做除法的同时求余数

		BigDecimal n = new BigDecimal("12.345");
        BigDecimal m = new BigDecimal("0.12");
        BigDecimal[] dr = n.divideAndRemainder(m);
        System.out.println(dr[0]); // 102 商
        System.out.println(dr[1]); // 0.105 余数

signum()

根据正负返回-1、0、1,返回0表示等于0

  • equals()compareTo()

    在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等;

    必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于。

    BigDecimal d1 = new BigDecimal("123.456");
    BigDecimal d2 = new BigDecimal("123.45600");
    System.out.println(d1.equals(d2)); // false,因为scale不同
    System.out.println(d1.equals(d2.stripTrailingZeros())); // true,因为d2去除尾部0后scale变为3
    System.out.println(d1.compareTo(d2)); // 0
    

    总是使用compareTo()比较两个BigDecimal的值,不要使用equals()!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值