BigDecimal can be understood as a floating point number whose size can be arbitrarily specified and whose precision is accurate. It is used in everyday money-related fields such as amount, interest, etc. Since it has been used more recently, it is recorded for reference to avoid problems.

1. Construction method of common usage

// Use string, no loss of precision (recommended)
// Result: 0.1
 BigDecimal bigDecimal = new BigDecimal("0.1"); 

// If int is used, there is a loss of accuracy
/ / the result: 0.1000000000000000055511151231257827021181583404541015625
 BigDecimal bigDecimal2 = new BigDecimal(0.1);
Copy the code

Ps: String and BigDecimal convert each other

// String to BigDecimal
String str = "100.01";
BigDecimal bigDecimal = new BigDecimal(str); 

// BigDecimal converts to a string
BigDecimal big = new BigDecimal("13.14"); 
String string = big.toString();
String string2 = String.valueOf(big);
Copy the code

2 Use scale in BigDecimal

1 scale

Scale is a member property of BigDecimal,final keyword modifier, cannot be modified, and represents the number of decimal places.

        BigDecimal d1 = new BigDecimal("12.10");
        BigDecimal d2 = new BigDecimal("123.1000");
        BigDecimal d3 = new BigDecimal("1234500");
		// The decimal place is 2
        System.out.println(d1.scale()); 
		// The decimal place is 4
        System.out.println(d2.scale()); 
`		// The decimal place is 0
        System.out.println(d3.scale()); 
Copy the code

2 stripTrailingZeros() method used

The stripTrailingZeros() method in BigDecimal can be converted to a new BigDecimal, removing the trailing digit 0.

        BigDecimal d1 = new BigDecimal("123.4500");
        BigDecimal d2 = d1.stripTrailingZeros();
		// The decimal place is 4
        System.out.println(d1.scale()); 
		// The decimal place is 2, because 00 is removed
        System.out.println(d2.scale()); 

        BigDecimal d3 = new BigDecimal("1234500");
        BigDecimal d4 = d3.stripTrailingZeros();
		// The decimal place is 0
        System.out.println(d3.scale()); 
		// The decimal place is -2
        System.out.println(d4.scale()); 
Copy the code

Conclusion:

1 The scale() method of a BigDecimal object returns a negative number, such as -2, indicating that the number is an integer with two zeros at the end

2 IF a BigDecimal object does not end with a 0, call the stripTrailingZeros() method and the result remains the same.

3 Precision conversion

type instructions
ROUND_DOWN Get rid of the extra bits
ROUND_UP Carry forward processing
ROUND_CEILING If the value is positive, it is ROUND_UP. If the value is negative, it is ROUND_DOWN
ROUND_FLOOR If the value is positive, it is ROUND_DOWN. If the value is negative, it is ROUND_UP
ROUND_HALF_UP Round (>=5)
ROUND_HALF_DOWN Round, greater than 5, round (>5)
ROUND_HALF_EVEN If the digit to the left of the discarded part is even, HALF_DOWN; If the number on the left of the discarded part is odd, it is ROUND_HALF_UP
ROUND_UNNECESSARY Asserts that the requested operation has an exact result, so no rounding is required
// The old and new descriptions of patterns are different, but have the same effect
        // Get rid of the extra bits
        // 1 RoundingMode.DOWN == BigDecimal.ROUND_DOWN
        BigDecimal b = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_DOWN);
        System.out.println(b);

        // The reverse is true
        // 2 RoundingMode.UP == BigDecimal.ROUND_UP
        BigDecimal c = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_UP);
        System.out.println(c);

        // If positive, equivalent to BigDecimal.ROUND_UP; If it is negative, it is equivalent to BigDecimal.ROUND_DOWN
        // 3 RoundingMode.CEILING == BigDecimal.ROUND_CEILING
        BigDecimal f = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_CEILING);
        System.out.println(f);
        BigDecimal g = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_CEILING);
        System.out.println(g);

        // If positive, equivalent to BigDecimal.ROUND_DOWN; If it is negative, it is equivalent to BigDecimal.ROUND_HALF_UP
        // 4 RoundingMode.FLOOR == BigDecimal.ROUND_FLOOR
        BigDecimal h = new BigDecimal("2.225667").setScale(2, BigDecimal.ROUND_FLOOR);
        System.out.println(h);
        BigDecimal i = new BigDecimal("2.224667").setScale(2, BigDecimal.ROUND_FLOOR);
        System.out.println(i);

        // Round (if discard part >=.5, round)
        // 5 RoundingMode.HALF_UP == BigDecimal.ROUND_HALF_UP
        BigDecimal d = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_UP);
        System.out.println("ROUND_HALF_UP" + d);

        // Round (if discard part >.5, round)
        // 6 RoundingMode.HALF_DOWN == BigDecimal.ROUND_HALF_DOWN
        BigDecimal e = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_DOWN);
        System.out.println("ROUND_HALF_DOWN" + e);

        ROUND_HALF_DOWN ROUND_HALF_DOWN ROUND_HALF_DOWN If the number on the left of the discarded part is odd, it is ROUND_HALF_UP
        // 7 RoundingMode.HALF_EVEN == BigDecimal.ROUND_HALF_EVEN
        BigDecimal j = new BigDecimal("2.225").setScale(2, BigDecimal.ROUND_HALF_EVEN);
        System.out.println(j);
        BigDecimal k = new BigDecimal("2.215").setScale(2, BigDecimal.ROUND_HALF_EVEN);
        System.out.println(k);


        // Assert that the requested operation has an exact result, so no rounding is required. Throw ArithmeticException if you specify this rounding mode for operations that get exact results.
        // 8 RoundingMode.UNNECESSARY == BigDecimal.ROUND_UNNECESSARY
        BigDecimal bigDecimal = new BigDecimal("2.215").setScale(3, BigDecimal.ROUND_UNNECESSARY);
        System.out.println(bigDecimal);


Copy the code

3 BigDecimal operations

1 plus, minus, multiply and divide

Calculation of addition, subtraction, multiplication, there will be no loss of precision, division operation, if there is no division, you need to specify the precision.

        BigDecimal n = new BigDecimal("123.456");
        BigDecimal m = new BigDecimal("23.456789");

        / / add
        System.out.println(n.add(m));
        / / subtraction
        System.out.println(n.subtract(m));
        / / the multiplication
        System.out.println(n.multiply(m));
        / / division
        // Error: ArithmeticException, because it is ArithmeticException
	   // System.out.println(n.divide(m));
        // Keep 10 decimal places and round them
        System.out.println(n.divide(m, 10, RoundingMode.HALF_UP));
Copy the code

2 divideAndRemainder () method

The returned array contains two BigDecimal, the quotient and the remainder, where the quotient is always an integer and the remainder is no greater than the divisor.

        BigDecimal n = new BigDecimal("12.75");
        BigDecimal m = new BigDecimal("0.15");
        BigDecimal[] dr = n.divideAndRemainder(m);
        if (dr[1].signum() == 0) {
            System.out.println("N is an integer multiple of m.");
        }

        System.out.println(dr[0]);
        System.out.println(dr[1]);
Copy the code

3 compareTo () method

Comparing two BigDecimal places, do not use the ==equals() method ==, since the ==equals() method == requires both BigDecimal values to be equal and the decimal places of the two objects to be equal.

        BigDecimal d1 = new BigDecimal("123.1");
        BigDecimal d2 = new BigDecimal("123.10");
        
        // false, because scale is different
        System.out.println(d1.equals(d2));
        // true, because d2 removes the tail 0 and scale becomes 2
        System.out.println(d1.equals(d2.stripTrailingZeros())); 
Copy the code

The comparison of BigDecimal uses the ==compareTo() method ==, which returns negative,0, and positive numbers based on the result of comparing two objects

        / / equal to 0
        BigDecimal d1 = new BigDecimal("123.1");
        BigDecimal d2 = new BigDecimal("123.1");
        System.out.println(d1.compareTo(d2));

        / / is greater than 1
        BigDecimal d3 = new BigDecimal("123.2");
        BigDecimal d4 = new BigDecimal("123.1");
        System.out.println(d3.compareTo(d4));

        / / less than 1
        System.out.println(d4.compareTo(d3));
Copy the code

In use, try to make a judgment comparison close to 0. It is said that the comparison result may be a decimal number, but the blogger has not found it for the time being.

Note:

Always compare two BigDecimal values using compareTo(), not equals()!