# BigDecimal

学一个东西,必须带着问题去学习...【为什么?】【是什么?】【怎么用?】

# 为什么要用BigDecimal?

首先,看一个现象

okAFr8.png

为啥会出现这种情况呢?

不论是float还是double在计算机中都是二进制的,浮点数会失去一定的精度(十进制数的二进制表示形式可能不精确,只能无限接近于那个值)

但是,在项目中,我们不可能让这种情况出现,特别是金融项目,因为涉及金额的计算都必须十分精确,你想想,如果你的支付宝账户余额显示193.99999999999998,那是一种怎么样的体验?

# BigDecimal是什么?

Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算

  1. 构造器推荐使用 BigDecimal(String)
  2. 方法:
  • add(BigDecimal)
  • subtract(BigDecimal)
  • multiply(BigDecimal)
  • divide(BigDecimal)
  • toString()
  • doubleValue()
  • intValue()

# 怎么用?

okAEVg.md.png

okAkqS.md.png

再进行除法运算的时候,暴怒能整除(有余数)会报错java.lang.ArithmeticException,避免报错,需要多传两个参数

divide(BigDecimal,保留小数点后几位小数,舍入模式)

舍入模式

  • ROUND_UP 在丢弃非零部分之前始终增加数字(始终对非零舍弃部分前面的数字加1)
  • ROUND_DOWN 在丢弃某部分之前始终不增加数字(从不对舍弃部分前面的数字加1,即截断)。
  • ROUND_CEILING 如果 BigDecimal 为正,则舍入行为与 ROUND_UP 相同,如果为负,则舍入行为与 ROUND_DOWN 相同
  • ROUND_FLOOR 如果 BigDecimal 为正,则舍入行为与 ROUND_DOWN 相同;如果为负,则舍入行为与 ROUND_UP 相同
  • ROUND_HALF_UP 在小学时就学过的舍入模式(四舍五入)
  • ROUND_HALF_DOWN 五舍六入
  • ROUND_HALF_EVEN 1.15>1.2 1.25>1.2
  • ROUND_UNNECESSARY

okAiKf.md.png

  1. 举个例子: 一套房子由于各种原因现在只卖156w,比以前降价14w,计算降幅?

现在卖:1560000,以前卖:1560000+140000,降价140000 降幅 = 降价 / 以前卖 = 140000 / (1560000+140000) * 100%

    BigDecimal price_now = new BigDecimal("1560000");
    BigDecimal price_jiang = new BigDecimal("140000");
    BigDecimal price_before = price_now.add(price_jiang);

    String rs = price_jiang.divide(price_before, 2, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100)).toString() + "%";
    System.out.println(rs);
1
2
3
4
5
6

参考:https://blog.csdn.net/qq_35868412/article/details/89029288