[Java] 숫자를 0으로 나눌 때의 자료형별 동작과 예외 발생 케이스

2025. 6. 12. 15:06·Java

 

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
'Java' 카테고리의 다른 글
  • [Java] Java16 에 추가된 Pattern Matching for instanceof
  • [Java] synchronized block 이해하고 사용하기
  • [Java] 자바 객체의 Lock 과 Monitor 이해하기
  • [Java] Blocking Queue 이해하고 사용해보기
기억은 RAM, 기록은 HDD
기억은 RAM, 기록은 HDD
  • 기억은 RAM, 기록은 HDD
    적립식 개발
    기억은 RAM, 기록은 HDD
  • 전체
    오늘
    어제
    • 분류 전체보기 (45)
      • Gradle (1)
      • 알고리즘 (14)
        • 강한 연결 요소 (1)
        • BFS (1)
        • 다이나믹 프로그래밍 (2)
        • 그리디 (1)
        • 투 포인터 (2)
        • 비트마스크 (1)
        • 스택 (1)
        • 백트래킹 (1)
        • 유니온-파인드 (1)
        • 기초 기하학 (1)
        • 분할정복을 이용한 거듭제곱 (1)
        • 볼록 껍질 (1)
      • JPA (3)
      • Java (9)
      • Spring (9)
      • Git&GitHub (2)
      • Infra (4)
  • 최근 글

  • 인기 글

  • 태그

    투 포인터
    java
    자바synchronized키워드
    자바 runnable
    @embedded
    spring cors 해결
    githubworkflow
    thread 와 runnable
    enum정리
    자바future
    java synchronized
    완전탐색
    데몬쓰레드
    정렬
    Github
    비트마스킹
    enum활용법
    기하학
    java 라이브러리 추가
    자바 callable
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.1
기억은 RAM, 기록은 HDD
[Java] 숫자를 0으로 나눌 때의 자료형별 동작과 예외 발생 케이스
테마상단으로

티스토리툴바