돈 계산이나 소수점 단위의 정밀한 계산을 할 때는 float이나 double을 절대 사용하면 안된다.
double, float)은 부정확할까?컴퓨터는 모든 숫자를 이진수(0과 1)로 저장한다. 정수는 이진수로 변환하기 쉽지만, 소수점 이하의 숫자는 이진수로 변환할 때 무한 소수가 되는 경우가 많다.
double sum = 0;
for(int i = 0; i < 10; i++) {
sum += 0.1;
}
System.out.println(sum);
// 결과: 0.9999999999999999 (1.0이 아님!)
이 미세한 오차가 쌓이면 거대한 금융 사고나 시스템 오류로 이어질 수 있다.
소수점을 없애고 정수(int, long) 단위로 계산한 뒤, 마지막에만 소수점을 찍어 표현하는 방법
1.0 - 7 * 0.1 = 0.299999...int apple = 1;
int totalPieces = apple * 10; // 10조각
int number = 7;
int result = totalPieces - number; // 10 - 7 = 3 (정수 연산은 정확함)
System.out.println("남은 양: " + result / 10.0); // 0.3
정수 변환이 너무 복잡하다면 java.math.BigDecimal 클래스를 사용하면 된다. 속도는 조금 느리지만, 소수점 계산을 완벽하게 정확히 처리한다.
import java.math.BigDecimal;
BigDecimal b1 = new BigDecimal("1.0");
BigDecimal b2 = new BigDecimal("0.7");
BigDecimal result = b1.subtract(b2);
System.out.println(result); // 결과: 0.3 (정확함)
주의: BigDecimal을 쓸 때 new BigDecimal(0.1)처럼 숫자를 직접 넣으면 안 된다. new BigDecimal("0.1")처럼 문자열로 생성해야 오차가 발생하지 않는다.
float, double)은 부동 소수점 방식을 써서 미세한 오차가 있다.BigDecimal을 써야 한다.