피드로 돌아가기
올리브영 테크블로그Backend
원문 읽기
부동소수점 이야기
올리브영 정산 스쿼드가 부동소수점 연산 방식 대신 BigDecimal을 도입해 금액 계산의 반올림 오차 제거
AI 요약
Context
Java의 기본 실수형(double, float)은 10진수를 2진수로 변환하는 과정에서 근사치 값으로만 표현 가능하기 때문에, 정산 시스템에서 금액 계산 시 0.1 + 0.2 ≠ 0.3 같은 오차가 발생한다. 이러한 부동소수점 정밀도 문제는 누적 계산 과정에서 최종 결과값의 정수 단위 차이를 야기해 계산 오류로 이어질 수 있다.
Technical Solution
- 부동소수점 방식을 고정소수점 방식으로 전환: 기본 자료형(double) 대신 BigDecimal 사용
- 문자열 기반 초기화 적용: new BigDecimal("0.1")과 같이 문자열로 초기화해 부동소수점 한계 우회
- 십진수 기반 내부 저장: BigDecimal은 내부적으로 십진수로 숫자를 저장해 0.1 같은 십진수를 정확히 표현
- BigDecimal 연산 메서드 사용: add(), subtract(), multiply(), divide() 등의 메서드로 정확한 계산 수행
- 스케일 및 반올림 모드 지정: setScale()과 RoundingMode(FLOOR, CEILING, HALF_UP, HALF_EVEN 등)를 조합해 필요한 정밀도 설정
Key Takeaway
금액 계산을 다루는 금융·정산 도메인에서는 연산 속도보다 정확성이 우선되므로, 반드시 BigDecimal을 사용해 부동소수점 방식의 근본적 한계를 제거해야 한다.
실천 포인트
정산, 결제, 회계 같은 금액 관련 계산을 담당하는 Java 애플리케이션에서 BigDecimal을 사용하되, 문자열로 초기화하고 divide() 호출 시 명시적으로 RoundingMode를 지정하면 원화 단위 이상의 계산 오차를 완벽히 방지할 수 있다.