BIGDECIMAL 사용시 주의점

BigDecimal.divide() 메서드 사용시

반올림 모드를 지정하지 않는다면, 나눗셈의 결과가 무한소수 인 경우 ArithmeticException 이 발생할 수 있다.

BigDecimal 은 기본적으로 정확한 값을 요하는데,

예를 들어

1 / 3 같은 계산을 BigDecimal 로 계산하려고 하는 경우, 0.3333333…. 으로 무한한 소수가 됨.

그래서 특정한 반올림모드가 필요함.

API reference for Java Platform, Standard Edition
Each rounding mode description includes a table listing how different two-digit decimal values would round to a one digit decimal value under the rounding mode in question. The result column in the tables could be gotten by creating a BigDecimal number with the specified value, forming a MathContext object with the proper settings (precision set to 1, and the roundingMode set to the rounding mode in question), and calling round on this number with the proper MathContext. A summary table showing the results of these rounding operations for all rounding modes appears below.
https://docs.oracle.com/en/java/javase/11/docs/api///java.base/java/math/RoundingMode.html
  • 위는 반올림 모드에 관련한 내용이다.

종류

  • RoundingMode.UP
    • 0에서 멀어지는 방향으로 반올림합니다.
  • RoundingMode.DOWN
    • 0에 가까워지는 방향으로 반올림합니다.
  • RoundingMode.CEILING
    • 양의 무한대 방향으로 반올림합니다.
  • RoundingMode.FLOOR
    • 음의 무한대 방향으로 반올림합니다.
  • RoundingMode.HALF_UP
    • 가장 가까운 숫자로 반올림하며, 정확히 중간값인 경우에는 위로 반올림합니다.
  • RoundingMode.HALF_DOWN
    • 가장 가까운 숫자로 반올림하며, 정확히 중간값인 경우에는 아래로 반올림합니다.
  • RoundingMode.HALF_EVEN
    • 가장 가까운 숫자로 반올림하며, 정확히 중간값인 경우에는 짝수를 향해 반올림합니다 (이것은 "은행가의 반올림"이라고도 합니다).
  • RoundingMode.UNNECESSARY
    • 계산 결과가 정확하게 나누어 떨어지는 경우에만 사용되며, 그렇지 않을 경우 예외를 발생시킵니다.

사용

public BigDecimal calculateDiscount(int quantity, int discountRate) {
	BigDecimal unitPrice = BigDecimal.valueOf(this.unitPrice);
	BigDecimal quantityDecimal = BigDecimal.valueOf(quantity);
	BigDecimal discountRateDecimal = BigDecimal.valueOf(discountRate).divide(BigDecimal.valueOf(100), MathContext.DECIMAL128);
	
	return unitPrice.multiply(quantityDecimal).multiply(discountRateDecimal);
}
    public static final MathContext DECIMAL128 =
        new MathContext(34, RoundingMode.HALF_EVEN);
  • 소수점 이하 34자리의 정밀도를 가지며,
  • 반올림 모드로 RoundingMode.HALF_EVEN
  • RoundingMode.HALF_EVEN은 "은행가 반올림” 이라고 부른다고 합니다.
    • 은행가 반올림
      • 반복된 반올림 과정에서 오류를 줄이기 위해 등장한 개념으로
      • 금융에서는 수관련 많은 계산이 필요합니당.
      • 해당 계산들이 누적되어 작은 오차라도 큰 영향을 미치기에, 이러한 오차를 최소화하기 위해 은행가 반올림 을 사용한다고 합니다.
        • 왜 오차를 최소화할 수 있으냐?
          • 2.5 같이 정확히 중간에 위치한 숫자를 반올림하는 경우
          • 2로
          • 3.5 을 반올림한다면
          • 4로
          • 항상 짝수값을 도출하게 됩니다.
          • 즉,
            • 상황에 따라 올림과 내림이 균등하게 분포되도록 하며
            • 많은 수의 데이터를 반올림하는 경우 발생하는 편향을 줄일 수 있습니다

Uploaded by N2T