Java BigDecimal class

introduction

  float and double types of primary design goal is to scientific computing and engineering calculations. They perform a binary floating-point arithmetic, which is to provide more accurate over a wide area fast approximate calculation of the value range and well designed. However, they do not provide fully accurate results, it should not be the case for applications requiring accurate results. However, commercial computing often require precise results, which will come in handy when BigDecimal friends.

  Look at the results of running the code below:

System.out.println(0.2+0.1);

Construction method

  1.public BigDecimal (double val) converts the double representation as BigDecimal  * not recommended

  2.public BigDecimal (int val) int representation as to convert BigDecimal

  3.public BigDecimal (String val) String to convert the representation into a BigDecimal

  Look below run the code:

        BigDecimal bigDecimalDouble = new BigDecimal(2.3);
        BigDecimal bigDecimalInteger = new BigDecimal(1);
        BigDecimal bigDecimalString = new BigDecimal("1.0");

        System.out.println(bigDecimalDouble);
        System.out.println(bigDecimalInteger);
        System.out.println(bigDecimalString);

  operation result:

   Why does this happen?

   JDK description:

    1, there is a certain type of parameter unpredictability of results of double construction method. One might think that BigDecimal newBigDecimal written in Java (0.1) created exactly equal to 0.1 (unscaled value is 1, and whose scale is 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 can not be accurately expressed as a double (or, for that matter, can not be expressed as a binary fraction of any finite length). In this way, passed to the constructor is not exactly equal to the value of 0.1 (although this value is equal to the upper surface).

          2, on the other hand, String constructor is entirely predictable: Write newBigDecimal ( "0.1") creates a BigDecimal, which is exactly equal to the expected 0.1. Therefore, in contrast, it is generally recommended to use String constructor priority .

 Math Algorithms

  For conventional addition, subtraction, multiplication, division, the BigDecimal class provides methods corresponding member.

        BigDecimal a = new BigDecimal("4.5");
        BigDecimal b = new BigDecimal("0.3");


        System.out.println("a+b=" + a.add(b));
        System.out.println("a-b=" + a.subtract(b));
        System.out.println("a*b=" + a.multiply(b));
        System.out.println("a/b=" + a.divide(b));

  Results are as follows:

Division rounding

  One thing to note here is the division divide.

  BigDecimal除法可能出现不能整除的情况,比如 4.5/1.3,这时会报错java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

  其实divide方法有可以传三个参数

  public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) 

  第一参数表示除数, 第二个参数表示小数点后保留位数,第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式,有下面这几种

CEILING    //向正无穷方向舍入

DOWN    //向零方向舍入

FLOOR    //向负无穷方向舍入

HALF_DOWN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5

HALF_EVEN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN

HALF_UP    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6

UNNECESSARY    //计算结果是精确的,不需要舍入模式

UP    //向远离0的方向舍入

总结

  1. 商业计算使用BigDecimal。
  2. 尽量使用参数类型为String的构造函数。
  3. BigDecimal都是不可变的(immutable)的,在进行每一步运算时,都会产生一个新的对象,所以在做加减乘除运算时千万要保存操作后的值。
  4. 我们往往容易忽略JDK底层的一些实现细节,导致出现错误,需要多加注意。

Guess you like

Origin www.cnblogs.com/huanghzm/p/12044633.html