-
[이펙티브 자바] item 60 - 정확한 답이 필요하다면 float와 double은 피하라개발서적읽기/Effective Java - temp 2020. 5. 13. 23:00
■실수의 표현 방식
컴퓨터에서 실수를 표현하는 방법은 정수에 비해 훨씬 복잡하다.
왜냐하면, 컴퓨터에서는 실수를 정수와 마찬가지로 2진수로만 표현해야 하기 때문.
아래의 2가지 실수 표현 방식이 있다.
- 고정 소수점(fixed point) 방식
부동 소수점(floating point) 방식
고정 소수점 방식에 비해 부동 소수점 방식은 표현할 수 있는 범위가 훨씬 크다.
대부분의 시스템에서 부동 소수점 방식을 사용중이다.
그리고 현재 사용되고 있는 부동 소수점 방식은 대부분 IEEE 754 표준을 따르고 있다.
float와 double 변수도 이 부동 소수점 방식을 사용중이다.
■부동 소수점 방식의 단점
부정확하다!
IEEE 754의 값을 계산하는 고유한 수식때문에
float(32 bit)는 소수 9번째 자리, double(64 bit)는 소수 15번째 자리까지만
정확히 표현할 수 있고 그 이후는 부정확하다.
System.out.println(1.03 - 0.42);
//0.6100000000000001
System.out.println((1.00 - 9 * 0.10));
//0.09999999999999998■대안 : BigDecimal, int, long 사용
- 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);
}참고로 BigDecimal은 내부적으로 char 배열을 사용하여 값을 처리한다
public BigDecimal(char[] in, int offset, int len, MathContext mc)
- 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은 값의 크기가 제한되고 소수점을 직접 관리해야 한다는 단점이 있다.
상황에 알맞은 타입을 잘 골라서 쓰면 되겠다!
'개발서적읽기 > Effective Java - temp' 카테고리의 다른 글
[이펙티브 자바] item 26 - 로 타입은 사용하지 말라 (0) 2020.07.19 [이펙티브 자바] item 14 - Comparable을 구현할지 고려하라 (0) 2020.07.09 [이펙티브 자바] item 71 - 필요 없는 검사 예외 사용은 피하라 (0) 2020.05.21 [이펙티브 자바] item 70 - 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라 (0) 2020.05.20 [이펙티브 자바] item 61 - 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) 2020.05.15 댓글
- 고정 소수점(fixed point) 방식