Java BigDecimal usage guide

Speaking of BigDecimal, I believe everyone has used it. The reason for summarizing this article is that it was recently discovered that the use of the project is not too standardized. In some scenarios, the code even throws exceptions.

So I summarized this article, I hope you can step on some pits less when you use it.

1. Basic operations

1.1 Addition

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.add(number2);
System.out.println("number1 add number2 = " + number3);

Output result:

number1 add number2 = 100.00

1.2 Subtraction

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.subtract(number2);
System.out.println("number1 subtract number2 = " + number3);

Output result:

number1 subtract number2 = 77.76

1.3 Multiplication

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.multiply(number2);
System.out.println("number1 multiply number2 = " + number3);

Output result:

number1 multiply number2 = 988.3456

1.4 Division

BigDecimal number1 = new BigDecimal("88");
BigDecimal number2 = new BigDecimal("11");

BigDecimal number3 = number1.divide(number2);
System.out.println("number1 divide number2 = " + number3);

Output result:

number1 divide number2 = 8

Because the above two numbers can be divided evenly, there is no problem in using this method. However, once they cannot be divided evenly, there will be potential risks and java.lang.ArithmeticExceptionexceptions when used in this way . Therefore, it is strongly recommended to use it like the following :

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.divide(number2, 2, RoundingMode.HALF_UP);
System.out.println("number1 divide number2 = " + number3);

Output result:

number1 divide number2 = 7.99

The source code of the divide() method used at this time is as follows:

public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
    
    
    return divide(divisor, scale, roundingMode.oldMode);
}

The scale here refers to the number of decimal places to be kept, and we pass it 2, which means keeping 2 decimal places.

The roundingMode here refers to the rounding mode, and what we pass here is RoundingMode.HALF_UPthe rounding mode that is often used.

1.5 Keep decimal places

If we want to reserve the number of decimal places for the BigDecimal type, we can use the setScale() method, as shown below:

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.multiply(number2);
System.out.println("number1 multiply number2 = " + number3);

// 保留3位小数,四舍五入
BigDecimal number4 = number3.setScale(3, RoundingMode.HALF_UP);
System.out.println("number3 setScale = " + number4);

Output result:

number1 multiply number2 = 988.3456

number3 setScale = 988.346

1.6 Compare size

To compare the size of BigDecimal, you can use the compareTo() method, as shown below:

BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = new BigDecimal("11.11");
BigDecimal number3 = new BigDecimal("99.99");
BigDecimal number4 = new BigDecimal("88.88");

System.out.println("number1 compareTo number2 = " + number1.compareTo(number2));
System.out.println("number1 compareTo number3 = " + number1.compareTo(number3));
System.out.println("number1 compareTo number4 = " + number1.compareTo(number4));

Output result:

number1 compareTo number2 = 1

number1 compareTo number3 = -1

number1 compareTo number4 = 0

It can be seen from the output result:

When number1 is less than number2, return -1,

When number1 is equal to number2, return 0,

When number1 is greater than number2, 1 is returned.

2. Summary

2.1 NullPointerException

When using the BigDecimal type for calculations, such as the above-mentioned addition, subtraction, multiplication, division, and comparison, you must ensure that the two values ​​involved in the calculation cannot be empty, otherwise java.lang.NullPointerExceptionan exception will be thrown .

For example, the following two pieces of code will throw exceptions:

BigDecimal number1 = null;
BigDecimal number2 = new BigDecimal("11.12");

BigDecimal number3 = number1.add(number2);
System.out.println("number1 add number2 = " + number3);
BigDecimal number1 = new BigDecimal("88.88");
BigDecimal number2 = null;

BigDecimal number3 = number1.add(number2);
System.out.println("number1 add number2 = " + number3);

The exception thrown is shown below:

2.2 ArithmeticException

When using BigDecimalthe dividemethod once, java.lang.ArithmeticExceptionan exception is thrown , and the error code is as follows:

// 含税金额
BigDecimal inclusiveTaxAmount = new BigDecimal("1000");
// 税率
BigDecimal taxRate = new BigDecimal("0.13");
// 不含税金额 = 含税金额 / (1+税率)
BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate));

System.out.println(exclusiveTaxAmount);

The following exception is thrown at runtime:

java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

The reason for the error is that it cannot be divisible, resulting in an infinite loop decimal:

The solution is to specify the rounding mode, such as our most commonly used rounding mode:

// 不含税金额 = 含税金额 / (1+税率)
BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate),RoundingMode.HALF_UP);

At this time, no error is reported, and the output result is:

885

But my requirement here is to keep 2 decimal places and round up, so the code should look like this:

// 不含税金额 = 含税金额 / (1+税率)
BigDecimal exclusiveTaxAmount = inclusiveTaxAmount.divide(BigDecimal.ONE.add(taxRate), 2, RoundingMode.HALF_UP);

The output at this time is:

884.96

If your IDEA is installed with the Alibaba code specification plug-in, if not specified RoundingMode, there will be the following prompt:

3. Specification

Try not to use new BigDecimal("0")it in the project , but use the constants provided by BigDecimal BigDecimal.ZERO.

BigDecimal zero = BigDecimal.ZERO;
BigDecimal one = BigDecimal.ONE;
BigDecimal ten = BigDecimal.TEN;

Note: If you feel that this blog has any errors or better suggestions, please leave a message, I will follow up and correct the blog content in time!

The article is continuously updated, welcome to follow the WeChat public account "Shencheng Yixiangren" to read it for the first time!

Guess you like

Origin blog.csdn.net/zwwhnly/article/details/108273779