컴퓨터 프로그래밍에서 실수 연산은 흔히 오차 문제를 동반합니다.
특히 금융, 과학 계산, 그리고 데이터 분석 등 정확한 수치가 중요한 분야에서는 이 문제가 더욱 부각되는 문제인데요.
이번 글에서는 Double의 한계, Float를 사용한 실수 연산의 특징, 그리고 BigDecimal을 활용한 오차 없는 실수 연산 방법을 살펴보겠습니다.
1. Double의 문제: 부동소수점 연산의 한계
Double은 대부분의 프로그래밍 언어에서 기본 실수형으로 사용됩니다.
이는 64비트 IEEE 754 표준을 따르며, 빠른 연산 속도와 넓은 범위의 숫자를 처리할 수 있는 장점이 있습니다.
하지만 정확도 면에서는 한계가 있습니다.
public class DoubleExample {
public static void main(String[] args) {
double a = 0.1;
double b = 0.2;
double c = a + b;
System.out.println("0.1 + 0.2 = " + c);
}
}
출력 결과.
0.1 + 0.2 = 0.30000000000000004
왜 이런 일이 발생할까요?
- Double은 2진수 기반의 부동소수점 표현 방식을 사용합니다.
- 10진수 0.1과 0.2를 정확히 표현할 수 없기 때문에, 이진수로 변환될 때 근삿값으로 저장됩니다.
- 이로 인해 연산 결과에도 미세한 오차가 발생합니다.
2. Float 사용: 더 작은 범위, 더 큰 오차
Float는 Double보다 작은 32비트 부동소수점 자료형입니다.
메모리 사용량이 적고 연산 속도가 빠르지만, 표현할 수 있는 유효 숫자 범위가 좁습니다.
public class FloatExample {
public static void main(String[] args) {
float a = 0.1f;
float b = 0.2f;
float c = a + b;
System.out.println("0.1f + 0.2f = " + c);
}
}
출력 결과.
0.1f + 0.2f = 0.3
겉보기에는 정확해 보이지만, 실제로는 내부에서 근삿값을 저장하고 있어 더 작은 숫자 범위에서 더 큰 오차가 발생할 가능성이 높습니다.
Float의 주요 특징
- 적합한 경우: 높은 정밀도가 요구되지 않는 경우 (예: 게임 개발, 그래픽 연산).
- 부적합한 경우: 금융 계산이나 통계 연산 등 오차가 치명적인 경우.
3. BigDecimal 사용: 실수 연산의 정밀도 보장
BigDecimal은 Java에서 제공하는 클래스 중 하나로, 정확한 실수 연산을 보장하기 위해 사용됩니다.
이 클래스는 실수를 10진법 기반으로 처리하므로, 부동소수점의 근삿값 문제를 해결할 수 있습니다.
import java.math.BigDecimal;
public class BigDecimalExample {
public static void main(String[] args) {
BigDecimal a = new BigDecimal("0.1");
BigDecimal b = new BigDecimal("0.2");
BigDecimal c = a.add(b);
System.out.println("0.1 + 0.2 = " + c);
}
}
출력 결과.
0.1 + 0.2 = 0.3
중요 사항
- new BigDecimal(double)로 생성할 경우 부동 소수점의 오차가 그대로 발생할 위험성이 존재합니다.
- "scale()"메서드로 소수 자릿수를 설정하여 계산 결과를 정리할 수 있습니다.
그럼 뭘 사용해야 할까?
실수 연산은 문제 되는 상황을 인지하고 있지 않다면 쉽게 간과할 수 있는 중요한 이슈입니다.
특히 환율, 이율 등과 같이 금전적인 부분이 연결되어 있다면 이는 서비스의 신뢰도를 낮추게 되는 매우 크리티컬 한 문제가 될 수 있습니다.
그렇기 때문에 위에 주어진 Double, Float, BigDecimal들을 잘 활용하여 적재적소에 사용해야 하는 것은 중요한 기본이라 생각합니다.
'Java' 카테고리의 다른 글
[ThreadLocal] Thread영역에 데이터를 저장하고 싶어요 (1) | 2025.01.27 |
---|---|
[Java] Static (3) | 2024.12.26 |
[ Basic ] I/O Stream이란? (0) | 2024.12.23 |
[JPA] 비관적 락 낙관적 락 (0) | 2024.06.29 |
JPA는 어떤 기술일까? (0) | 2024.04.12 |