60. 정확한 답이 필요하다면 float와 double은 피하라

📝 아이템 60: 정확한 답이 필요하다면 float와 double은 피하라

🔹 핵심 요약

✅ float와 double은 근사치 계산에 적합하며 정확한 결과가 필요할 때는 적합하지 않음 ✅ 금융 계산 같은 정확한 계산에는 BigDecimal, int 또는 long을 사용해야 함 ✅ BigDecimal은 정확하지만 사용이 불편하고 느림 ✅ 성능이 중요하고 소수점을 직접 관리할 수 있다면 int나 long을 권장


📚 필수 개념 정리

🧮 부동소수점 vs 고정소수점 vs BigDecimal 비교

특성
부동소수점(float/double)
고정소수점(int/long)
BigDecimal

정밀도

제한적 (IEEE 754 표준)

소수점 직접 관리 (정수)

임의 정밀도 (무제한)

표현 범위

매우 넓음 (±1.7E±308)

제한적 (int: ~21억, long: ~922경)

사실상 무제한

정확성

부정확 (근사값)

정확 (범위 내에서)

정확 (십진수 표현)

성능

매우 빠름

빠름

느림 (~10배)

메모리

적음 (4/8바이트)

적음 (4/8바이트)

많음 (가변)

사용 편의성

쉬움

소수점 관리 필요

편리하지만 코드 복잡성 증가

적합한 용도

과학/공학, 센서값 계산

임베디드, 간단한 금융 계산(소규모)

금융/정밀 수치 계산

오차 발생

필연적

없음 (적절히 구현 시)

발생하지 않음

반올림 제어

제한적

직접 구현 필요

세밀한 제어 가능

이 코드의 결과는?

→ 결과는 0.9999999999999999 \n false

👉 왜 이런 결과가 나올까?

  • 부동소수점의 한계: 0.1과 같은 일부 십진수는 컴퓨터에서 정확한 이진수로 표현되지 못해 작은 오차가 발생

  • 오차 누적: 아무리 오차가 작더라도 10번의 덧셈 과정에서 누적되어 최종 결과가 1.0이 아닌 0.999999...로 계산됨

💡 부동소수점의 한계

  • float와 double은 IEEE 754 부동소수점 방식을 사용

  • 2진수로 실수를 표현하기 때문에 0.1과 같은 십진수를 정확히 표현할 수 없음

  • 근사값으로 계산되어 금융 계산 등에서 오차 발생 가능

  • 걸프전 당시 미군의 패트리어트 미사일 시스템이 미사일 요격에 실패

  • 원인은 0.1초를 이진 부동소수점으로 정확히 표현하지 못한 오차

  • 시스템 가동 시간이 길어질수록 누적된 오차가 커졌고, 결과적으로 스커드의 위치 예측이 약 500m 이상 빗나가 요격 실패


🚨 잘못된 금융 계산 예시

float/double을 사용한 금액 계산

BigDecimal을 사용한 정확한 계산

⚠️ BigDecimal 사용 시 주의: double 값으로 BigDecimal을 생성하면 이미 오차가 있는 값이 전달됨 ▶️ String으로 생성


💼 BigDecimal의 장단점

👍 장점

  • 정확한 실수 계산이 가능해, 금융 계산 등에 적합함

  • 반올림, 올림, 내림 등을 RoundingMode를 통해 세밀하게 제어할 수 있음

  • 정밀도(precision) 를 자유롭게 설정 가능하여 오차 없는 계산 가능

👎 단점

  • +, -, *, / 같은 기본 연산자 사용 불가 → add(), subtract() 등 메서드로만 연산 가능

  • 기본 자료형보다 성능이 느림 (약 10배 정도 느리다고 알려져 있음)

  • 일반적으로 기본 자료형에 비해 더 많은 메모리 사용량이 필요하고, 정밀도를 직접 수정할 수 있어 정밀도가 높으면 메모리 사용량이 많이 증가함

🔧 활용 예시: 할인율 계산


🔄 int/long을 사용한 방법

🔢 단위 변환 접근법

금액을 계산할 때 달러나 원화 같은 단위 대신 센트나 전 단위로 계산하는 방법


📊 성능 비교


🎯 언제 어떤 타입을 사용할까?

🧠 선택 가이드

상황
권장 타입
이유

금융 계산

BigDecimal

정확한 계산이 필수적인 경우

고성능 필요

int/long

성능이 중요하고 소수점 관리가 가능할 때

9자리 이하의 소수점

int

정확한 계산 + 성능 (overflow 주의)

18자리 이하의 소수점

long

정확한 계산 + 성능 (더 큰 범위)

과학/공학 계산

double

정확도보다 넓은 범위의 근사치 계산이 필요할 때

간단한 근사치 계산

float/double

정확한 값이 필요 없는 일반 계산


🎯 결론

📍 금융 계산 같은 정확한 결과가 필요할 때는 float나 double을 피하라

📍 정확한 답이 필요하면 BigDecimal, int 또는 long을 사용하라

📍 성능, 편의성, 정확성 중 우선순위를 정하고 적합한 타입을 선택하라

📍 BigDecimal은 정확하지만 사용이 불편하고 느림을 인지하라

📍 소수점을 직접 관리할 수 있고 성능이 중요하다면 int나 long을 선택하라


💭 느낀 점

💡 금융 계산에서 왜 BigDecimal이 필수적으로 사용되는지, 그리고 실무에서 얼마나 중요한지 체감하게 됨

💡 프로그래밍 언어의 특성과 자료형의 한계를 이해하고 적절한 상황에 맞는 도구를 선택하는 것이 얼마나 중요한지 다시 한번 생각해 보게 됨

Last updated