<aside> 💡 float과 double 타입은 정확한 결과가 필요할 때는 사용하면 안된다. 소수점 추적은 시스템에 맡길 것!

</aside>

0.1, 10의 음의 거듭 제곱 수 (10^-2) 표현 못함

System.out.println(1.03, -0.42);
//0.6100000000000001

System.out.println(1,00 -9 * 0.10);
//0.0999999999999998

어설픈 코드

public class Change {

    public static void main(String[] args) {
        double funds = 1.00;
        int itemsBought = 0;
        for (double price = 0.10; funds >= price; price += 0.10) {
            funds -= price;
            itemsBought++;
        }
        System.out.println(itemsBought + " items bought.");
        System.out.println("Change: $" + funds);
    }
}

//3개 구입 후 잔돈은 0.39999999999... 달러가 남는다

BigDecimal 사용

BigDecimal이 제공하는 여덟 가지 반올림 모드 이용해 반올림 완벽히 제어 가능하다.

앞의 코드에서 double 타입을 BigDecimal로 교체

public class BigDecimalChange {
    public static void main(String[] args) {
    //BigDecimal 생성자 중 문자열 받는 생성자를 사용 
    //-> 계산 시 부정확한 값이 사용되는 것을 막기 위해 필요함
        final BigDecimal TEN_CENTS = new BigDecimal(".10");

        int itemsBought = 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);
            itemsBought++;
        }
        System.out.println(itemsBought + " items bought.");
        System.out.println("Money left over: $" + funds);
    }
}

//사탕 4개 구입 후 잔돈이 0

int 혹은 long 타입 사용

성능이 중요하고 소수점 직접 추적 가능하고