float
과 double
타입은 과학과 공학 계산용으로 설계되었다. 따라서 정확한 결과가 필요한 금융 관련 계산과는 맞지 않는다.
금융 계산에는 BigDecimal, int 혹은 long을 사용해야 한다.
public static void main(String[] args) {
final BigDecimal TEN_CENTS = new BigDecimal(".10");
int itemBought = 0;
BigDecimal funds = new BigDecimal("1.00");
for (BigDecimal price = TEN_CENTS; funds.compareTo(price) >= 0; price = price.add(TEN_CENTS)) {
funds = funds.subtract(price);
itemBount++;
}
}
이렇게 하면 사탕 4개를 구입후 정확히 0달러가 남는다.
BigDecimal은 기본타입보다 훨씬 느리고 불편하다.
BigDecimal 대신 int 혹은 long을 쓸 경우 값의 크기가 제한되고 소수점을 직접 관리해야 한다.
BigDecimal
에는 문자열을 넘겨야지, double
을 넘기면 안된다. double
형을 넘기면서 그 순간 정확도를 보장하지 못한다.
BigDEcimal value = new BigDecimal("12.23");
그렇다면 BigDecimal
의 정확도는 어느정도까지일까?
BigDecimal은 기본적으로 정수 표현을 위해 BigInteger을 사용합니다. 공식 문서에 따르면 BIgInteger는 -2^Integer.MAX_VALUE ~ +2^Integer.MAX_VALUE 를 지원한다고 합니다. 더 큰 값도 이론적으로 가능하지만 Java 가상 머신이 가지고 있는 메모리 양으로 제한됩니다.
정리하면 지정된 범위의 숫자에 대한 공식 지원이 있지만 충분한 컴퓨팅 자원이 있는 경우 더큰 숫자도 비공식적으로 사용할 수 있다고 합니다!
https://github.com/woowacourse-study/2022-effective-java/pull/39