반응형
이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.
아이템 60. 정확한 답이 필요하다면 float와 double은 피하라
float, double
- 과학과 공한 계산용으로 설계된 데이터 타입이다.
- 이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 근사치로 계산하도록 설계되었다.
- 정확한 결과가 필요한 금융 관련 계산과는 어울리지 않는다.
- 1.03 - 0.42의 결과를 0.6100000000001을 출력한다.
ex 1) 금융 계산 시에 부동소수 타입을 사용한 잘못된 예
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.39999999999999999
- 이렇듯 부동소수 타입을 이용하면 정확한 계산 결과가 나오지 않기 때문에,
금융 계산에는 BigDecimal, int 혹은 long을 사용해야 한다.
ex 2) ex 1의 예를 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 = 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을 사용하면 정확한 결과를 도출할 수 있다.
- 다만, 기본 타입보다 쓰기가 훨씬 불편하고, 느리다.
ex 3) ex 1의 예를 int로 구현한 예
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);
}
- BigDecimal의 대안으로 int 혹은 long 타입을 사용할 수 있다.
- 대신 다룰 수 있는 값의 크기가 제한되고, 소수점을 직접 관리해야한다.
- 이 경우에는 모든 계산을 달러 대신 센트로 수행하도록 로직을 수정하였다.
정리
- 정확한 계산이 필요할 때에는 float과 double을 사용하지 말자.
- 대신, BigDecimal이나 int, long을 이용하자.
- BigDecimal은 사용하기 불편하고 성능 저하가 발생하지만, 다양한 기능을 제공하니 참고하자.
반응형
'BE > Java' 카테고리의 다른 글
[Effective Java] 아이템 62. 다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2022.11.29 |
---|---|
[Effective Java] 아이템 61. 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2022.11.28 |
[Effective Java] 아이템 59. 라이브러리를 익히고 사용하라 (0) | 2022.11.24 |
[Effective Java] 아이템 58. 전통적인 for 문보다는 for-each 문을 사용하라 (0) | 2022.11.23 |
[Effective Java] 아이템 57. 지역변수의 범위를 최소화하라 (0) | 2022.11.22 |