이펙티브 자바, 쉽게 정리하기 - item 60. 정확한 답이 필요하다면
float
과double
은 피하라
float
과 double
이 사용하는 이진 부동소수점의 취약점
@Test
public void floatDoubleTest1() {
System.out.println(1.03 - 0.42);
// 결과: 0.6100000000000001
}
float
과double
은 이진 부동소수점 연산에 쓰여 근사치로 계산하도록 설계된 타입이다.- 위 코드의 경우
0.61
이 그대로 나오지 않고,0.6100000000000001
이 나오게 된다. - 이진수로 소수점을 표현하는 데 한계가 있고, 그 한계가 이진 부동소수점을 사용함으로써 여실히 드러난다.
- 이를테면
0.1
을 2진수로 표현하면0.0001100,1100,...
와 같이 순환소수로 표현해야 한다.- 이러한 순환소수를 비트 수의 한계까지 표현하다보면 위와 같은 결과가 나온다.
- 이를테면
해결 방법
@Test
public void bigDecimalTest() {
BigDecimal bigDecimal1 = new BigDecimal("1.03");
BigDecimal bigDecimal2 = new BigDecimal("0.42");
System.out.println(bigDecimal1.subtract(bigDecimal2));
// 결과: 0.61
}
BigDecimal
,int
,long
등을 사용하여 정수로 연산해야 한다.BigDecimal
의 생성자 중 반드시 문자열로 숫자를 받는 생성자를 이용해야 한다.- 그래야만 값이 정확하게 나온다.
핵심 정리
- 소수점이 들어가는 연산을 하는데, 정확한 답이 필요할 때는
float
과double
을 사용하지 말자. - 약간의 성능저하가 있더라도
BigDecimal
을 사용하는 것이 정확하다.
반응형
'Java > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바, 쉽게 정리하기 - item 62. 다른 타입이 적절하다면 문자열 사용을 피하라 (0) | 2023.06.23 |
---|---|
이펙티브 자바, 쉽게 정리하기 - item 61. 박싱된 기본 타입보다는 기본 타입을 사용하라 (0) | 2023.06.22 |
이펙티브 자바, 쉽게 정리하기 - item 59. 라이브러리를 익히고 사용하라 (0) | 2023.06.22 |
이펙티브 자바, 쉽게 정리하기 - item 58. 전통적인 for 문보다는 for-each 문을 사용하라 (0) | 2023.06.22 |
이펙티브 자바, 쉽게 정리하기 - item 57. 지역변수의 범위를 최소화하라 (0) | 2023.06.21 |