[Item 60] 정확한 답이 필요하다면 float과 double은 피하라

2022. 8. 14. 11:19JAVA/Effective Java

float과 double 타입은 넓은 범위의 수를 바르게 정밀한 '근사치'로 계산하도록 새삼하게 설계되어있다.

float과 double 타입은 금융 관련 계산과 맞지 않으므로 정확한 결과가 필요할때는 사용하면 안된다.

 

잘못된 예시

package effectivejava.chapter9.item60;

public class Change {
    // 코드 60-1 오류 발생! 금융 계산에 부동소수 타입을 사용했다. (356쪽)
    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 + "개 구입");
        System.out.println("잔돈(달러): " + funds);// 0.3999999999999999 출력됨
    }
}

실행해보면 사탕 3개를 구입 후 잔돈이 0.39999999999999999 달러가 남아있음을 알게된다. 잘못된 계산의 예시로 금융 계산에는 BigDecimal, int 혹은 long을 사용해야 한다.

 

올바른 예시

package effectivejava.chapter9.item60;

import java.math.BigDecimal;

public class BigDecimalChange {
    // 코드 60-2 BigDecimal을 사용한 해법. 속도가 느리고 쓰기 불편하다. (356쪽)
    public static void main(String[] args) {
        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 + "개 구입");
        System.out.println("잔돈(달러): " + funds);
    }
}

실행하면 사탕 4개를 구입한 후 잔돈은 0달러가 남는다. 정답이다.

대신 BigDecimal에는 단점이 두가지가 있다. 

  • 기본타입보다 쓰기가 훨씬 불편하고, 훨씬 느리다.
  • BigDecimal 대안으로는 int 혹은 long 타입을 쓸 수도 있다. 그럴 경우, 값의 크기가 제한되고, 소수점을 직접 관리해야한다.

 


핵심정리

  • 정확한 답이 필요한 계산에는 float과 double을 피하라.
    • 소수점 추적은 시스템에 맡기고 성능을 신경쓰지 않는다면 BigDecimal
    • 성능이 중요하고 소수점을 직접 추적할 수 있고 숫자가 너무 크지 않다면 int나 long
    • 숫자를 아홉 자리 십진수로 표현할 수 있다면 int 사용, 열여덟 자리 십진수로 표현할 수 있다면 long 사용, 열여덟 자리를 넘어가면 BigDecimal 사용

참고자료

www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966262281&orderClick=LEa&Kc=

 

이펙티브 자바 3/E - 교보문고

프로그래밍인사이트 | 자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브러리의 최신 기능을 십분 활용

www.kyobobook.co.kr