반응형
728x90
반응형
float와 double 타입의 단점
float 와 double 타입은 과학과 공학 계산용으로 설계되었다. 이는 정확한 결과가 필요할 때는 사용하면 안된다. float와 double 타입은 특히 금융 관련 계산과는 맞지 않는다. 0.1 혹은 10의 음의 거듭제곱수 등을 표현할 수 없기 때문이다.
오류 발생하는 코드
package com.java.effective.item60;
public class Main {
public static void main(String[] args) {
double funds = 1.00;
int itemBought = 0;
for (double price = 0.10; funds >= price; price += 0.10) {
funds = funds - price;
itemBought++;
}
System.out.println(itemBought + "개 구입");
System.out.println("잔돈(달러):" + funds);
}
}
금융 계산에 부동소수 타입을 사용했다. 이는 결과가 아래와 같다.
결과
3개 구입
잔돈(달러):0.3999999999999999
이는 잘못된 결과다. 이 문제를 올바로 해결하려면, BigDecimal, int 혹은 long을 사용해야한다.
BigDecimal 사용으로 변경
BigDecimal 로 변경
package com.java.effective.item60;
import java.math.BigDecimal;
public class Main2 {
public static void main(String[] args) {
final BigDecimal TEN_CNETS = new BigDecimal("0.10");
int itemsBought = 0;
BigDecimal funds = new BigDecimal("1.00");
for (BigDecimal price = TEN_CNETS;
funds.compareTo(price) >= 0; price = price.add(TEN_CNETS)) {
funds = funds.subtract(price);
itemsBought++;
}
System.out.println(itemsBought + "개 구입");
System.out.println("잔돈(달러): " + funds);
}
}
위 코드는 아래 결과와 같이 올바른 답이 나온다.
결과
4개 구입
잔돈(달러): 0.00
BigDecimal의 단점
기본 타입보다 훨씬 쓰기 불편하고, 훨씬 느리다. BigDecimal의 대안으로 int 혹은 long 타입을 쓸 수도 있다. 그럴 경우 다룰 수 있는 값의 크기가 제한되고, 소수점을 직접 관리해야 한다. 이번 예시는 달러 대신 센트로 수행하면 훨씬 빠르고 편리하게 구현할 수 있다.
int 타입
package com.java.effective.item60;
import java.math.BigDecimal;
public class Main3 {
public static void main(String[] args) {
int itemsBought = 0;
int funds = 100;
for (int price = 10; funds >= price; price += 10) {
funds = funds - price;
itemsBought++;
}
System.out.println(itemsBought + "개 구입");
System.out.println("잔돈(달러): " + funds);
}
}
결과
4개 구입
잔돈(달러): 0
상황에서의 선택
1) int
숫자를 아홉자리 십진수로 표현할 수 있을 경우
2) long
열여덟 자리 십진수로 표현할 수 있을 경우
3) BigDecimal
열여덟 자리를 넘어가는 경우
반응형
'Book > Effective Java' 카테고리의 다른 글
[교재 EffectiveJava] 아이템 62. 다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2021.12.04 |
---|---|
[교재 EffectiveJava] 아이템 61. 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2021.12.03 |
[교재 EffectiveJava] 아이템 59. 라이브러리를 익히고 사용하라 (0) | 2021.12.01 |
[교재 EffectiveJava] 아이템 58. 전통적인 for 문보다는 for-each문을 사용하라 (0) | 2021.11.30 |
[교재 EffectiveJava] 아이템 57. 지역변수의 범위를 최소화하라 (0) | 2021.11.29 |