BigDecimal operation and 8 rounding modes

BigDecimal is an immutable, arbitrary-precision signed decimal number.
It is generally used in fields that require high numerical precision such as large-amount settlements (because floating-point numbers such as float and double have insufficient precision to represent decimals, and can only handle 16 significant digits), but its computing performance is lower than Double, Float, etc. In general engineering field numerical calculations, BigDecimal will not be used casually.

This article will introduce the addition, subtraction, multiplication, and division of BigDecimal and 8 rounding modes.

Construction method

There are 4 commonly used constructors:

  • BigDecimal(double val)
  • BigDecimal(int val)
  • BigDecimal(long val)

  • The constructors above BigDecimal(String val) get infinite precision decimals, that is, there is no limit to the number of decimal places reserved

These four constructors can construct double, long, int, and String types as BigDecimal objects. First, it is recommended to use BigDecimal(String val), and secondly, it is not recommended to use BigDecimal(double val) to create, because double represents 0.1 is not accurate, and if you use new BigDecimal(0.1), the value obtained is still inaccurate. The results of its operation are as follows:

Construct BigDecimal with doubleConsole output

After the object is created, the addition, subtraction, multiplication, and division operations cannot directly use +, -, *, /, but use the following methods:

  • Addition:, the add(BigDecimal augend)return is BigDecimal, its value is (this+augend)
  • Subtraction:, the subtract(BigDecimal subtrahend)return is BigDecimal, its value is (this-subtrahend)
  • Multiplication:, the multiply(BigDecimal multiplicand)returned BigDecimal, its value is (this * multiplicand)
  • Division:, the divide(BigDecimal divisor)returned BigDecimal, its value is (this / divisor), but this is not recommended

Division recommends the following API with precise decimal places and clear carry method

divide(BigDecimal divisor, int scale, int roundingMode)

Addition, subtraction, multiplication and division

BigDecimal a=new BigDecimal("1000");
BigDecimal b=new BigDecimal("0.001");

//加法: 1000.001
BigDecimal bigDecimal = a.add(b);

//减法:999.999
BigDecimal bigDecimal = a.subtract(b); 

//乘法:1.000
BigDecimal bigDecimal = a.multiply(b);

//除法:1000000.000
BigDecimal bigDecimal = a.divide(b);
BigDecimal bigDecimal = a.divide(b,2,RoundingMode.HALF_UP);

It is worth noting that division generally requires determining how many decimal places to keep BigDecimal bigDecimal = a.divide(b,2,RoundingMode.HALF_UP);. If the reserved scale is not set, ArithmeticException may be thrown. This is because the ROUND_UNNECESSARY mode is a.divide(b)used by default , that is, no rounding is performed. If the decimal place of the calculation result does not match the required decimal place , an exception will be thrown.

8 rounding modes

1. ROUND_UP

Direct carry
bigDecimal.setScale(2,BigDecimal.ROUND_UP)

  • The first parameter newScale: newScale:2keep 2 decimal places
  • The second parameter BigDecimal.ROUND_UP: direct carry

such as:

					1000 - 0.011=999.989 
	BigDecimal.ROUND_UP		 =>  999.99
	保留小数点后两位,第二位的“8”进位成“9”,变成了999.99        								   

2. ROUND_DOWN

Discard extra decimals

bigDecimal.setScale(2,BigDecimal.ROUND_DOWN)
  • The first parameter newScale: newScale:2only keep 2 decimal places
  • The second parameter BigDecimal.ROUND_DOWN: discard the extra decimal places after the second digit
					1000 - 0.011=999.989 
	BigDecimal.ROUND_DOWN	 =>  999.98
	将第二位以后的“9”舍弃,变成了999.98	

3. ROUND_CEILING

Go up

bigDecimal.setScale(2,BigDecimal.ROUND_CEILING)

Positive and negative numbers are handled differently: positive numbers are carried, and negative numbers are discarded after the decimal

  • Positive number 999.989 => 999.99, the second "8" carry
  • Negative number -999.989 => -999.98, the decimal after the second digit is discarded

4. ROUND_FLOOR

Take the small value

bigDecimal.setScale(2,BigDecimal.ROUND_FLOOR)
  • Positive number 999.989 => 999.98
  • Negative number -999.989 => -999.99

5. ROUND_HALF_DOWN

Round to six

bigDecimal.setScale(2,BigDecimal.ROUND_HALF_DOWN)
  • ROUND_HALF_DOWN: requires the third decimal placeRound to six (Because newScale=2 retains two decimal places)

for example:

  • 1000-0.005=999.995 -->999.99 five rounds
  • 1000-0.004=999.996 -->1000.00 six entries

6. ROUND_HALF_UP

rounding

bigDecimal.setScale(2,BigDecimal.ROUND_HALF_UP)
  • newScale: 2 is to operate on the third digit after the decimal point
  • ROUND_HALF_UP: third decimal placerounding

such as:

  1. 1000-0.006=999.994 -->999.99 rounds
  2. 1000-0.005=999.995 -->1000.00 five in

7. ROUND_HALF_EVEN

This is a bit more complicated

When the discarded number <5 discarded,>5 carry , it depends on the situation when =5:

bigDecimal.setScale(0,BigDecimal.ROUND_HALF_EVEN)

Without keeping the decimal point:

  • 5.5 -> 6: If the left digit of the discarded number "5" is an odd number , the rounding behavior is the same as ROUND_HALF_UP(rounding)
  • 2.5 -> 2: If the left digit of the discarded number "5" is an even number , the rounding behavior is the same as ROUND_HALF_DOWN(Round to six)
  • 5.55 -> 6: If the distance between the discarded number "5" and two adjacent numbers (both are 5) is equal, then round to the adjacent even number (basically also rounding , such as 4.44 -> 4, 6.66 -> 7)

8.ROUND_UNNECESSARY

The programmer can be sure that the calculation result is accurate, so no rounding is done. But if the final number does not meet the newScale requirements to keep decimal places, ArithmeticException will be thrown.

bigDecimal.setScale(0,BigDecimal.ROUND_UNNECESSARY)

In the case of not keeping decimals, select the ROUND_UNNECESSARY strategy:

digital Results of the
6.6 ArithmeticException
6.0 6
5.5 ArithmeticException
5.0 5

Guess you like

Origin blog.csdn.net/qq_44384533/article/details/108727964