1. BigDecimal이란?
BigDecimal은 자바에서 제공하는 클래스로, 정확하고 정밀한 실수 연산을 위해 사용되는 클래스입니다. 실수를 표현하는 데 있어서 double이나 float보다 더 큰 범위의 숫자와 더 높은 정밀도를 제공합니다. BigDecimal은 불변(immutable) 클래스이므로 값을 변경할 수 없으며, 새로운 BigDecimal 객체를 생성해야 값의 변경이 가능합니다. 이러한 특징으로 인해 대규모의 정확한 실수 연산이 필요한 금융 분야나 과학 연구 등에서 많이 사용됩니다.
BigDecimal 클래스는 크게 두 가지로 구분됩니다. 첫 번째는 정수부와 소수부를 각각 부호, 크기, 소수점 위치를 갖고 있는 부호화된 정확한 정수(rational exact integer)를 나타내는 Immutable 클래스인 BigDecimal입니다. 두 번째는 부호화된 실수(rational exact floating-point)를 나타내는 Mutable 클래스인 BigDecimal입니다. 두 가지 모두 정확한 연산을 제공하지만, 성능 면에서는 Immutable한 BigDecimal이 더 효율적입니다.
BigDecimal을 사용하여 고정 소수점 연산과 부동 소수점 연산을 수행할 수 있으며, 소수점 자리수의 제한 없이 원하는 만큼의 정밀도를 지정할 수 있습니다. 정확한 실수 연산을 위해 사용되는 BigDecimal 클래스는 실수 연산의 크기에 상관없이 일관된 결과를 제공하는 데 매우 유용합니다. 반대로 double이나 float은 정확한 실수 값을 제공하기 어렵고, 부동 소수점 연산에서 정확성이 상실될 수 있습니다.
BigDecimal 클래스를 사용하는 방법과 함께 실제 예제와 효율적인 활용 방법에 대해 알아보겠습니다.
2. BigDecimal 사용법
BigDecimal 클래스는 java.math 패키지에 포함되어 있으므로, 해당 패키지를 import 해야 합니다.
import java.math.BigDecimal;
BigDecimal 객체를 생성하려면 다음과 같은 방법을 사용할 수 있습니다.
BigDecimal.valueOf()
메서드를 사용하여 값을 전달하여 객체를 생성합니다.BigDecimal num1 = BigDecimal.valueOf(10.5); BigDecimal num2 = BigDecimal.valueOf(5.2);
new BigDecimal()
생성자를 사용하여 문자열을 전달하여 객체를 생성합니다.BigDecimal num3 = new BigDecimal("3.14159"); BigDecimal num4 = new BigDecimal("-123.45");
BigDecimal 객체는 내장 메서드를 통해 다양한 연산을 수행할 수 있습니다. 일반적인 연산자들과 관련된 메서드들도 지원되며, 연산 결과는 새로운 BigDecimal 객체로 반환됩니다.
BigDecimal result1 = num1.add(num2); // 덧셈
BigDecimal result2 = num1.subtract(num2); // 뺄셈
BigDecimal result3 = num1.multiply(num2); // 곱셈
BigDecimal result4 = num1.divide(num2); // 나눗셈
int result5 = num1.compareTo(num2); // 비교: -1, 0, 1 반환
boolean result6 = num1.equals(num2); // 동등성 비교
BigDecimal 객체는 불변성(immutability)을 가지므로, 값을 변경하고자 한다면 새로운 BigDecimal 객체를 생성해야 합니다.
정밀도와 반올림 방식을 지정할 수도 있습니다. setScale()
메서드로 원하는 소수점 이하 자리수와 반올림 모드를 설정할 수 있습니다.
BigDecimal num5 = new BigDecimal("3.14159");
BigDecimal rounded = num5.setScale(2, RoundingMode.HALF_UP); // 소수점 2자리로 반올림
정밀한 실수 연산을 위해 BigDecimal을 사용하는 경우, setScale()
을 통해 필요한 만큼의 정밀도를 지정하고 반올림 방식을 선택하는 것이 중요합니다. 또한, 연산 결과를 저장하기 위해 새로운 BigDecimal 객체를 생성하는 것을 잊지 말아야 합니다.
또한, BigDecimal은 BigDecimal 객체간의 비교와 동등성 검사에 사용될 때 compareTo()
와 equals()
메서드를 사용함에 주의해야 합니다. ==
연산자를 사용하면 객체의 주소를 비교하므로 원하는 결과를 얻을 수 없습니다.
BigDecimal의 사용법과 관련된 내용을 알아보았습니다. 다음으로는 BigDecimal을 효율적으로 사용하는 방법과 실제 예제에 대해 알아보겠습니다.
3. BigDecimal 예제 및 효율적인 활용 방법
예제: 부동 소수점 연산의 정확성 보장하기
부동 소수점 연산에서 정확한 결과를 얻기 위해 BigDecimal을 사용할 수 있습니다. 예를 들어, 0.1을 10번 더하는 연산을 수행하면, 부동 소수점 오차 때문에 예상한 결과와 다를 수 있습니다.
double num = 0.1;
double result = 0;
for (int i = 0; i < 10; i++) {
result += num;
}
System.out.println(result); // 0.9999999999999999
이와 같은 경우에는 BigDecimal을 사용하여 정확한 결과를 얻을 수 있습니다.
BigDecimal num = new BigDecimal("0.1");
BigDecimal result = BigDecimal.ZERO;
for (int i = 0; i < 10; i++) {
result = result.add(num);
}
System.out.println(result); // 1.0
효율적인 활용 방법
BigDecimal은 불변 객체이기 때문에, 매 연산마다 새로운 BigDecimal 객체를 생성해야 합니다. 그러나 객체 생성은 비용이 높은 작업이므로, 반복문 내에서 연산을 수행하는 경우에는 성능에 영향을 줄 수 있습니다.
이러한 경우, BigDecimal
대신 MutableBigDecimal
클래스를 사용할 수 있습니다. MutableBigDecimal
은 BigDecimal을 상속받아 연산을 수행하지만, 내부의 값은 변경 가능한(mutable) 상태를 유지합니다. 따라서 연산 시에 객체를 새로 생성하지 않고 내부 값을 변경하여 성능을 향상시킬 수 있습니다.
import org.apache.commons.lang3.mutable.MutableBigDecimal;
MutableBigDecimal num = new MutableBigDecimal("0.1");
MutableBigDecimal result = new MutableBigDecimal(BigDecimal.ZERO);
for (int i = 0; i < 10; i++) {
result.add(num);
}
System.out.println(result); // 1.0
이렇게 MutableBigDecimal을 사용하면 반복문 등에서 많은 연산을 수행할 때 성능상의 이점을 얻을 수 있습니다. 그러나 사용 시에 주의해야 할 점은, MutableBigDecimal은 내부 값이 변경 가능하기 때문에 적절한 동기화가 필요한 경우에 주의해야 합니다.
BigDecimal의 예제와 효율적인 활용 방법에 대해 알아보았습니다. BigDecimal은 정확한 실수 연산이 필요한 상황에서 유용하게 사용될 수 있습니다.