티스토리 뷰

float과 double을 BigDecimal, int, long으로 대체해라

 

❓ float와 double의 문제

float과 double 타입은 과학과 공학 계산용으로 설계되었다.

이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 설계되었다.

따라서 금융 관련 계산처럼 정확한 결과가 필요할 때 사용하면 안 된다.

 

금융 계산에 부동소수 타입을 사용해보자.

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);

프로그램을 실행해보면 사탕 3개를 구입한 후 잔돈은 0.3999999999999999달러가 남은 것으로 나온다.

이 문제를 해결하기 위해선 2가지 방법이 존재한다.

 

첫 번째, BigDecimal을 사용한다.

앞서 코드의 double 타입을 BigDecimal로 교체해보자.

BigDecimal의 생성자 중 문자열을 받는 생성자를 사용했음에 주목하자. 계산 시 부정확한 값이 사용되는 걸 막기 위해 필요한 조치다.

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 = TEM_CENTS; funds.compareTo(price)>=0 ; price=price.add(TEN_CENTS)){
    	funds = funds.subtrack(price);
        itemsBought++;
    }
    System.out.println(itemsBought + "개 구입");
    System.out.println("잔돈(달러) : " + funds);
 }

이렇게 BigDecimal을 사용하면 원하던 답 0이 잘 나온다.

하지만 BigDecimal은 기본 타입보다 쓰기가 훨씬 불편하고, 훨씬 느리다는 단점이 있다.

 

그렇다면 두 번째 방법 int 혹은 long 타입을 사용해보자.

int 혹은 long을 사용하면 다룰 수 있는 값의 크기가 제한되고, 소수점을 직접 관리해야 한다.

따라서 달러 대신 센트로 수행한다.

public static void main(String[] args){
	int itemsBought = 0;
    int funds = 100;
    for (int price = 10;funds >= price; price += 10){
    	funds -= price;
        itemsBought++;
    }
    System.out.println(itemsBought + "개 구입");
    System.out.println("잔돈(센트) : "+funds);
}

 

📚 정리하자!

1. 정확한 답이 필요한 계산에는 float이나 double을 피해라.
2. 소수점 추적은 시스템에 맡기고, 코딩 시의 불편함이나 성능 저하를 신경 쓰지 않겠다면 BigDecimal을 사용해라.
3. 숫자를 열여덟 자리 이상 십진수로 표현해야 한다면 BigDecimal을 사용해라.
4. 성능이 중요하고 소수점을 직접 추적할 수 있고 숫자가 너무 크지 않다면 int나 long을 사용해라.
5. 숫자를 아홉 자리 십진수로 표현할 수 있다면 int를 사용하고, 열 여덟 자리 십진수로 표현할 수 있다면 long을 사용해라.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함