Java에서 double이나 float은 부동소수점 오차가 존재하기 때문에 정확한 소수 계산이 필요한 경우에는 BigDecimal을 사용하는 것이 일반적입니다. 특히 금액 계산, 세금 계산, 금융 시스템에서는 정밀도가 중요한데, 이럴 때 BigDecimal이 유용하게 사용됩니다.
2. BigDecimal 비교는 왜 equals()가 아닌 compareTo()?
equals()는 값의 크기뿐만 아니라 소수점 자리수까지 정확히 일치해야 동일하다고 판단합니다. 예를 들어:
new BigDecimal("10.0").equals(new BigDecimal("10.00")) // false
new BigDecimal("10.0").compareTo(new BigDecimal("10.00")) // 0
따라서 숫자의 크기만 비교하고 싶다면 반드시 compareTo()를 사용해야 합니다.
3. compareTo() 사용법 정리
compareTo()는 다음과 같이 결과값을 반환합니다:
-1: 비교 대상보다 작을 때
0: 비교 대상과 같을 때
1: 비교 대상보다 클 때
BigDecimal a = new BigDecimal("100.00");
BigDecimal b = new BigDecimal("99.99");
int result = a.compareTo(b); // result = 1 (a가 b보다 큼)
4. 실무 예제: 가격 비교
BigDecimal price1 = new BigDecimal("1500.0");
BigDecimal price2 = new BigDecimal("1500.00");
if (price1.compareTo(price2) == 0) {
System.out.println("가격이 같습니다.");
} else if (price1.compareTo(price2) > 0) {
System.out.println("price1이 더 비쌉니다.");
} else {
System.out.println("price2가 더 비쌉니다.");
}
위 예제에서는 가격이 같다고 출력됩니다. 소수점 자리수가 달라도 compareTo는 값의 크기만 비교하기 때문입니다.
5. 주의할 점
equals()는 자리수까지 완벽히 같아야 true를 반환하므로 크기 비교엔 부적합합니다.
문자열로 생성하지 않고 new BigDecimal(0.1)처럼 생성하면 부동소수점 오차가 생깁니다.
BigDecimal x = new BigDecimal(0.1); // 위험: 정확하지 않음
BigDecimal y = new BigDecimal("0.1"); // 안전: 문자열로 생성
6. 실전 활용: 정렬과 비교
BigDecimal 배열을 오름차순으로 정렬하려면 다음과 같이 compareTo()를 이용합니다:
import java.util.*;
public class BigDecimalSort {
public static void main(String[] args) {
List<BigDecimal> list = Arrays.asList(
new BigDecimal("10.5"),
new BigDecimal("2.3"),
new BigDecimal("7.9")
);
list.sort((a, b) -> a.compareTo(b));
list.forEach(System.out::println);
}
}