N과 M을 둘다 int로 선언하면 안되는 이유
문제에서 설정한 N과 M의 범위는 [-2,000,000,000 ≤ N, M ≤ 2,000,000,000]
즉, int의 범위에 속한다.
하지만 주의해야 할 점은, N과 M이 사칙연산을 한다는 점이다.
+,- 연산으로 인해 -40억,+40억과 같은 int의 범위를 초과한 연산결과가 나올 수 있다는 소리다.
하지만, 문뜩 나는 이런 궁금증이 생겼다.
어차피 변수 N, M에 저장된 값은 변하지 않을텐데 왜 int로 하면 안되지? 결과값만 long으로 저장하면 안되나?
Math.abs에서 N-M을 알아서 long으로 봐줄 수는 없나?
Math.abs함수의 동작 방식 뭐지?
그래서 구글링한 결과 N과 M을 둘다 int로 선언하면 안되는 2가지의 구체적인 이유를 찾았다.
첫째, N과 M의 타입이 둘다 int라면, 둘의 연산 결과도 int로 저장된다.
N과 M 둘다 int이기 때문에, 둘의 연산인 N-M의 결과값은 int(32비트)로 CPU의 결과 레지스터에 저장된다. 알아서 long으로 봐주는 경우는 없다.
( 사실 이게 전부다. 여기서 연산 결과값이 int의 범위를 초과해서 짤리기 때문에 예상한 값이 안 나오는 것이다. 아래는 예시 코드다.)
둘째, Math.abs함수는 다음처럼 다양한 형태로 오버라이딩 되어있었다.
- int Math.abs(int a)
- long Math.abs(long a)
- float Math.abs(float a)
- double Math.abs(double a)
따라서 N과 M의 연산결과가 int이면, Math.abs의 반환값도 int일 수밖에 없다.
결론
그럼으로 이 문제는 N과 M을 ±40억을 포함할 수 있는 정수범위를 가진 자료형 long으로 선언해줘야 통과할 수 있는 문제다.
( 또는 자동 타입 변환을 활용해, N과 M 중 하나만 long으로 선언해도 된다. 그렇게 하면 연산결과를 CPU가 자동으로 long(64비트)로 레지스터에 저장하기 때문에 범위를 벗어나지 않는다.)
'백준' 카테고리의 다른 글
백준 15829 - Hashing - Java (0) | 2024.10.28 |
---|---|
백준 9935 - 문자열 폭발 - Java (1) | 2024.09.20 |
백준 2839번 - 설탕배달 문제 - Java (0) | 2023.07.17 |
백준 1018 - 체스판 문제 - Java (0) | 2023.07.16 |
백준 24313번 - BigO표기법 문제설명 - Java (0) | 2023.07.12 |