728x90
반응형
float, double
- 과학과 공학 계산용으로 설계된 타입
- 이진 부동소수점 연산에 사용되며, 넓은 범위의 수를 빠르고 정밀한 "근사치" 계산을 위해 세심하게 설계
→ 따라서 float과 double 타입은 특히 금융 관련과 같은 정확한 답이 필요한 계산에서는 사용하기 적절치 않다.
ex) 정확한 값을 구해야할 때 double, float을 사용하는 경우
// Q1. 1.03달러가 있을 때 그중 42센트를 사용할 경우 얼마가 남았을까?
System.out.println(1.03 - 0.42);
// -> result : 0.6.10000000000000001
// Q2. 1달러로 10센트짜리 사탕 9개를 살 경우에 얼마가 남았을까?
System.out.println(1.00 - 9 * 0.10);
// -> result : 0.0999999999999998
//금융계산에 부동소수 타입을 사용할 때 문제
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); // itemsBought -> 3
System.out.println("잔돈" + funds); // -> 0.39999999999999
}
금융 계산과 같은 정확한 값이 필요할 때는 BigDecimal, int, long 를 사용해야 한다.
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 + "개 구입"); // 사탕 4개
System.out.println("잔돈(달러): " + funds); // 잔돈 0달러
}
# BigDecimal의 단점
- 기본 타입보다 쓰기가 훨씬 불편하고 느리다.
- 단발성 계산이라면 느리다는 문제는 무시할 수 있지만 쓰기 불편하다는 점도 수반된다.
# BigDecimal의 대안으로 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);
}
정리
확한 답이 필요한 계산에는 float나 double을 피하라. 소수점 추정은 시스템에 맡기고, 코딩 시의 불편함이나 성능 저하를 신경 쓰지 않겠다면 BigDecimal을 사용하라.
BigDecimal이 제공하는 여덞 가지 반올림 모드를 이용하여 반올림을 완벽히 제어할 수 있다.
법으로 정해진 반올림을 수행해야 하는 비즈니스 계산에서 아주 편리한 기능이다.
반면, 성능이 중요하고 소수점을 직접 추적할 수 있고 숫자가 너무 크지 않다면 int나 long을 사용하라.
숫자를 아홉 자리 십진수로 표현할 수 있다면 int를 사용하고,
열여덞 자리 십진수로 표현할 수 있다면 long을 사용하라. 열여덞 자리를 넘어가면 BigDeciamal을 사용해야 한다.
728x90
반응형
'책 > Effective Java' 카테고리의 다른 글
다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2022.05.15 |
---|---|
박싱된 기본 타입 vs 기본 타입 (0) | 2022.05.14 |
메서드 참조 (Method Reference) (0) | 2022.03.20 |
lambda(람다) 사용법 (0) | 2022.03.20 |
마커 인터페이스(Marker Interface) (0) | 2022.03.20 |