Language/Java

BigDecimal

용용띠용 2025. 4. 18. 20:37

문제

: 실수 계산 시 정확한 값이 출력되지 않는다. 

    	double d1 = 0.10000000000000000009;
    	double d2 = 0.0000000000000000001;
    	
    	System.out.println("d1 - d2 = " + (d1 - d2));

-출력-

d1 - d2 = 0.1     //예상 출력값 = 0.09999999999999999999

 

 

원인

: Java는 IEEE 754 부동 소수점 방식을 사용해 정확한 실수가 아니라 근사치를 저장한다.

 

 

해결책

: java.math.BigDecimal 클래스

- 정수 값과 정밀도(소수점 이하 자릿수)를 따로 저장해 정수 값으로 연산 후 정밀도를 적용한다.

    	//double d1 = 0.10000000000000000009;
    	//double d2 = 0.0000000000000000001;
    	
    	BigDecimal d1 = new BigDecimal("0.10000000000000000009");
    	BigDecimal d2 = new BigDecimal("0.0000000000000000001");
    	
    	//System.out.println("d1 - d2 = " + (d1 - d2));
    	System.out.println("d1 - d2 = " + d1.subtract(d2));

-출력-

d1 - d2 = 0.09999999999999999999

 

 

BigDecimal

1. BigDecimal 클래스 내부 일부

example: 5.0143

 

- intVal

: unscaledValue()에 의해 소수점 정보가 배제된 정수를 담은 BigInteger 객체가 저장된다.

// 50143

 

- scale

: scale()에 의해 소수점 자리수를 저장한다.(소수점 첫째 자리 ~ 오른쪽부터 0이 아닌 수로 끝나는 위치)

// 4

 

- precision

: precision()에 의해 총 자리수를 저장한다.(왼쪽이 0이 아닌 수로 시작하는 위치 ~ 오른쪽이 0이 아닌 수로 끝나는 위치)

// 5

 

- signum()

: 부호를 저장한다

// 1

 

 

2. 선언

: BigDecimal 이름 = new BigDecimal("값");

- import java.math.BigDecimal 필요

- 파라미터를 String으로 받는 이유: 오차가 발생할 수 있기 때문이다. //정확도

 

 

3. 연산

: 메서드 활용

example: n1, n2 연산

 

1) 덧셈

: n1.add(n2);

 

2) 뺄셈

: n1.subtract(n2);

 

3) 곱셈

: n1.multiply(n2);

 

4) 나눗셈

: n1.divide(n2, scale, roundingMode);

 

- 반올림 처리: RoundingMode의 상수 이용

상수 역할
.CEILING 올림
.FLOOR 내림
.UP 양수: 올림, 음수: 내림
.DOWN 양수: 내림, 음수: 올림
.HALF_UP 반올림(5 이상: 올림, 5 미만: 버림)
.HALF_EVEN 반올림(반올림 자리값 짝수: HALF_DOWN, 홀수: HALF_UP)
.HALF_DOWN 반올림(5 이상: 올림, 5 미만: 버림)
.UNNECESSARY 나눗셈 결과 딱 안 떨어지면 ArithmeticException 발생

 

- 소수점 위치 변경

 

 

5) 나머지

: n1.remainder(n2);   // 결과값 음수여도 리턴

: n1.mod(n2);   // 결과값 음수면 ArithmeticException

6) 비교

: n1.compareTo(n2);

     - n1 < n2: -1

     - n1 == n2: 0

     - n1 > n2: 1

 

 

4. 형변환

example: n1 형변환

1) int

: n1.intValue();

 

2) long

: n1.longValue();

 

3) float

: n1.floatValue();

 

4) double

: n1.doubleValue();

 

5) String

: n1.toString();

 

 

5. 기본 상수

1) 0

: BigDecimal.ZERO;

 

2) 1

: BigDecimal.ONE;

 

3) 10

: BigDecimal.TEN;