Java에서는 숫자를 0으로 나눌 때 자료형에 따라 동작 방식이 다르다. 정수형(int, long)은 0으로 나누면 예외를 발생시키는 반면, 실수형(float, double)은 Infinity 또는 NaN(Not a Number)을 반환한다.
특히 실수일 때 JSON 직렬화 과정에서 String으로 변환되거나, 다른 연산에 영향을 미쳐 예상치 못한 버그가 생길 수 있으므로, 주의해야 한다.
정수를 0으로 나눌 때: ArithmeticException
int, long과 같은 정수형 데이터를 0으로 나누려고 하면, 자바는 이를 런타임 에러로 간주한다. 이때 java.lang.ArithmeticException이 발생하며 프로그램 실행이 중단된다.
int a = 10;
int b = 0;
try {
int result = a / b; // 여기서 ArithmeticException 발생!
System.out.println("결과: " + result);
} catch (ArithmeticException e) {
System.out.println("에러 발생: " + e.getMessage()); // 출력: 에러 발생: / by zero
}
부동 소수점 수를 0으로 나눌 때: Infinity 또는 NaN
반면, float 또는 double과 같은 부동 소수점(실수형) 데이터를 0.0으로 나누면, 정수 나눗셈과는 다르게 예외가 발생하지 않는다. 대신, IEEE 754 부동 소수점 표준에 따라 아래처럼 특수한 값을 반환한다.
- 양수 / 0.0: Positive Infinity (양의 무한대)
double result = 10.0 / 0.0; System.out.println("10.0 / 0.0 = " + result); // 출력: Infinity - 음수 / 0.0: Negative Infinity (음의 무한대)
double result = -10.0 / 0.0; System.out.println("-10.0 / 0.0 = " + result); // 출력: -Infinity - 0.0 / 0.0: NaN (Not a Number, 숫자가 아님)
double result = 0.0 / 0.0; System.out.println("0.0 / 0.0 = " + result); // 출력: NaN
예시 케이스
조합형 옵션을 가진 상품 도메인에서 단일 상품일 경우 originalPrice 를 내려주고, 옵션이 있는 상품은 originalPrice 를 null 로 내려주는 상황을 가정한다.

화면에 표시될 할인율을 포함해 반환하는 코드다. 여기서 휴먼 에러로 view.hasOption 의 조건이 잘못 작성되어 있다. (!view.hasOption 이어야 함)

이때 discountRate 계산 과정에서 double 연산이므로 originalPrice 에 0 이 들어가 있는 상황에서도 예외를 발생시키지 않는다.

결과적으로 -Infinity 가 반환되고

RestDocs 테스트상에서 String 으로 인식해 테스트가 실패한다.


실패한 이유를 간략히 설명하면 JSON 의 Number 타입과 Java 의 Number 타입의 불일치 때문이다. Java 에서 Double.NEGATIVE_INFINITY는 Double 형인데, JSON 의 Number Type 은 일반적인 10진수 숫자(정수 또는 소수점 포함) 이다.
스프링은 Jackson 으로 직렬화를 하는데 Jackson 라이브러리는 JSON 표준을 따르려고 한다. 따라서 -Infinity 를 String 으로 변환했고, RestDocs 상에서 TypeDoNotMatchException 이 발생했다.
테스트코드가 아니었으면 놓칠 수도 있었던 부분으로, Java 기본기가 중요함을 다시금 느낄 수 있었다.
'Java' 카테고리의 다른 글
| [Java] Java16 에 추가된 Pattern Matching for instanceof (0) | 2025.04.26 |
|---|---|
| [Java] synchronized block 이해하고 사용하기 (0) | 2025.03.09 |
| [Java] 자바 객체의 Lock 과 Monitor 이해하기 (0) | 2025.03.09 |
| [Java] Blocking Queue 이해하고 사용해보기 (1) | 2025.03.07 |
| [Java] Callable, Future 이해 및 사용예시 (0) | 2025.02.26 |
