| 타입 | 범위 |
|---|---|
long | 1.4E-45 ~ 3.4028235E38 |
double | 4.9E-324 ~ 1.7976931348623157E308 |
Java의 long, double 자료형은 부동 소수점을 사용하기 때문에 내부적으로 수를 저장할 때 이진수의 근사치를 저장한다. 따라서 소수점 이하 사칙연산 시 오차가 발생하여 정확한 값을 보장하지 않는다.
double value1 = 12.23;
double value2 = 34.45;
// 기대값 : 46.68
System.out.println(value1 + value2); // 46.68000000000001
위의 예제에서도 결과값으로 46.68이 출력될 것 같지만 실제로 46.68000000000001이 출력된다. 소수점을 정확하게 표현하는 것이 아니라 근사값으로 처리하기 때문이다. 이렇듯, 컴퓨터에서의 실수 표현은 근사값을 표현하는 것으로 이해해야 한다.
→ 이러한 문제 때문에 숫자에 민감한 금융 거래, 소수점 단위의 정확한 연산이 필요할 때는 BigDecimal을 사용한다.
BigDecimal을 사용해야 한다.
BigDecimal객체 생성 시String으로 생성해야 한다.
double로 생성하면 Java가 double 근사치를 BigDecimal에 넘겨주게 되어 오차가 발생할 수 있다.import java.math.BigDecimal; // math 클래스 import
// 문자열로 생성
BigDecimal bigDecimal = new BigDecimal("123.45678");
// double 타입으로 초기화하는 방법 - valueOf
// 내부적으로 생성자 + 문자열을 사용한다.
BigDecimal bigDecimal2 = BigDecimal.valueOf(123.456);
// 아래처럼 사용하지 말것!!!!
// 12.230000000000000426325641456060111522674560546875
BigDecimal bigDecimal3 = new BigDecimal(12.23);
BigDecimal은 문자열이기에 사칙연산이 불가능하다. 따라서 BigDecimal 클래스의 메서드를 사용해야 한다.
| 연산 | 메서드 |
|---|---|
| + | bigDecimal.add(BigDecimal val) |
| - | bigDecimal.subtract(BigDecimal val) |
| * | bigDecimal.multiply(BigDecimal val) |
| / | bigDecimal.divide(BigDecimal val) |
| % | bigDecimal.remainder(BigDecimal val) |
toPlainString()메서드를 통해2.0E7과 같은 지수(E) 표현을 제거할 수 있다.
// toPlainString() : 생성자로 전달받은 값을 지수 표현없이 반환한다.
public void toPlainString() {
System.out.println(new BigDecimal("2564000").toPlainString()); // 2564000
System.out.println(new BigDecimal("2.564E6").toPlainString()); // 2564000
}
Q.
A.