[코딩 테스트] 정수 자료형의 범위
문제 : 백준 11382번 꼬마 정민
처음에 그냥 덧셈문제라고만 생각하고 이전에 다른 사람들 답안을 보고 알아낸 BufferedReader를 활용해서 해봐야겠다 하고 코드를 작성했다.
첫번째 답안 :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String line = br.readLine();
br.close();
StringTokenizer st = new StringTokenizer(line);
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
int c = Integer.parseInt(st.nextToken());
System.out.println(a+b+c);
} catch (IOException e) {e.getMessage();
} catch (NumberFormatException e) {e.getMessage();
} catch (NullPointerException e) {e.getMessage();
} catch (Exception e) {e.getMessage();
}
}
}
BufferedReader와 StringTokenizer를 사용하고, int 타입으로 파싱해서 try-catch문 안에 작성해서 맞았을 거라고 생각했는데
한가지 확인하지 못한점이 있었다.
자료형 타입
A, B, C의 범위였다.
문제에서 (1 ≤ A, B, C ≤ 10^12) 이렇게 변수의 범위를 지정해줬는데
int 타입이 그 범위를 수용하지 못한다는 문제였다.
정수형 타입 | 할당되는 메모리의 크기 | 데이터의 표현 범위 |
byte | 1바이트 | -128 ~ 127 |
short | 2바이트 | -215 ~ (215 - 1) |
-32,768 ~ 32,767 | ||
int | 4바이트 | -231 ~ (231 - 1) |
-2,147,483,648 ~ 2,147,483,647 | ||
long | 8바이트 | -263 ~ (263 - 1) |
-9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
출처: https://inpa.tistory.com/entry/JAVA-☕-기본-자료형-종류-총정리-int-double-char-String [Inpa Dev 👨💻:티스토리]
위 표에서 알 수 있듯이 int타입은 10^12정도 되는 크기의 수를 수용할 수 없다.
대략 2*10^9 정도까지 표현할 수 있는 것을 알 수 있다.
unsigned
문제에서 입력이 1보다 크다고 했기 때문에 unsigned 타입을 활용하면 어떨까 했는데
우선을 그렇게 해도 범위가 부족하다.
타입 | 비트 수 | 일반 범위 | 양수로만 쓰는 경우 |
byte | 8 | -128 ~ 127 | 0 ~ 255 (unsigned) |
short | 16 | -32,768 ~ 32,767 | 0 ~ 65,535 |
char | 16 | 0 ~ 65,535 | ✔ 실제 unsigned |
int | 32 | -2,147,483,648 ~ 2,147,483,647 | 0 ~ 4,294,967,295 (toUnsignedLong() 활용) |
long | 64 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 |
0 ~ 18,446,744,073,709,551,615 (unsigned long 개념) |
그리고 Java에는 unsigned 자료형은 없다고 한다.
unsigned 자료형은 없지만,
✅ Integer.toUnsignedLong()
✅ Integer.compareUnsigned()
✅ Integer.divideUnsigned(), remainderUnsigned()
같은 헬퍼 메서드를 활용해서 unsigned 연산처럼 사용할 수 있다고 한다.
언어별 unsigned 지원 여부
언어 | unsigned 키워드 유무 | 예 |
C / C++ | ✅ 있음 | unsigned int a = ... |
C# | ✅ 있음 | uint a = ... |
Rust | ✅ 있음 | let a: u32 = ... |
Go | ✅ 있음 | var a uint = ... |
Java | ❌ 없음 (대신 메서드 제공) | Integer.toUnsignedLong() 등 |
Python | ❌ 없음 (유연한 정수형) | struct 등 활용 가능 |
맞춘 답안 :
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String line = br.readLine();
br.close();
StringTokenizer st = new StringTokenizer(line, " ");
long a = Long.parseLong(st.nextToken());
long b = Long.parseLong(st.nextToken());
long c = Long.parseLong(st.nextToken());
System.out.println(a+b+c);
} catch (IOException e) {e.getMessage();
} catch (NumberFormatException e) {e.getMessage();
} catch (NullPointerException e) {e.getMessage();
} catch (Exception e) {e.getMessage();
}
}
}
(파싱도 long으로 수정해야한다! 이거때문에 두번 제출ㅎ)