[Java의 정석] 정수형 - byte, short, int, long

말하는 감자·2023년 10월 29일
0

Java의 정석

목록 보기
19/32
post-thumbnail
post-custom-banner

Chapter 02 변수(Varialbe)

4. 기본형(primitive type)

📌 정수형 - byte, short, int, long

정수형에는 모두 4개의 자료형이 있으며, 각 자료형이 저장할 수 있는 값의 범위가 서로 다르다. 크기순으로 나열하면 다음과 같다. 단위는 byte이다.

byte부터 long까지 1 byte부터 시작해서 2배씩 크기가 증가한다. 이중에서도 기본 자료형(default data type)은 int이다.

📍 정수형의 표현형식과 범위

어떤 진법의 리터럴을 변수에 저장해도 실제로는 2진수로 바뀌어 저장된다. 이 2진수가 저장되는 형식은 크게 정수형과 실수형이 있으며, 정수형은 다음과 같은 형식으로 저장된다.

모든 정수형은 부호있는 정수이므로 왼쪽의 첫 번째 비트를 '부호 비트(sign bit)'로 사용하고, 나머지는 값을 표현하는 데 사용한다.
그래서 n비트로 표현할 수 있는 값의 개수인 2^n개에서, 절반인 '0'으로 시작하는 2^n-1개의 값을 양수(0도 포함)의 표현에서 사용하고, 나머지 절반인 '1'로 시작하는 2^n-1개의 값은 음수의 표현에서 사용한다.
그래서 정수형은 타입의 크기만 알면, 최대값과 최소값을 쉽게 계산해낼 수 있다.
범위의 최대값에서 1을 빼야하는데 이유는 범위에 0이 포함되기 때문이다. 예를 들어 byte의 경우 크기가 1 byte(=8 bit)이므로, byte타입의 변수에 저장할 수 있는 값의 범위는 '-128~127'이다.

📍 정수형의 선택기준

변수에 저장하려는 정수값의 범위에 따라 4개의 정수형 중에서 하나를 선택하면 되겠지만, byteshort보다 int를 사용한다. byteshortint보다 크기가 작아서 메모리를 조금 더 절약할 수는 있지만, 저장할 수 있는 값의 범위가 작은 편이라서 연산 시에 범위를 넘어서 잘못된 결과를 얻기 쉽다.
그리고 JVM의 피연산자 스택(operand stack)이 피연산자를 4 byte다위로 저장하기 때문에 크기가 4 byte보다 작은 자료형(byte, short)의 값을 계산할 때는 4 byte로 변환하여 연산이 수행된다. 그래서 오히려 int를 사용하는 것이 더 효율적이다.

결론적으로 정수형 변수를 선언할 때는 int타입으로 하고, int의 범위(약 ±20억)를 넘어서는 수를 다뤄야할 때는 long을 사용하면 된다.
그리고 byteshort은 성능보다 저장공간을 절약하는 것이 더 중요할 때 사용하자.

📍 정수형의 오버플로우

만일 4 bit 2진수의 최대값인 '1111'에 1을 더하면 어떤 결과를 얻을까?
4 bit의 범위를 넘어서는 값이 되기 때문에 에러가 발생할까?

원래 2진수의 '1111'에 1을 더하면 '10000'이 되지만, 4 bit로는 4자리의 2진수만 저장할 수 있기 때문에 '0000'이 된다. 즉, 5자리의 2진수 '10000'중에서 하위 4 bit만 저장하게 되는 것이다.
이처럼 연산과정에서 해당 타입이 표현할 수 있는 값의 범위를 넘어서는 것을 오버플로우(overflow)라고 한다. 오버플로우가 발생했다고 해서 에러가 발생하는 것은 아니다. 다만 예상했던 결과를 얻지 못할 뿐이다. 애초부터 오버플로우가 발생하지 않게 충분한 크기의 타입을 선택해서 사용해야 한다.
4자리의 10진수와 2지누의 오버플로우

그러면 이번엔 반대로 최소값인 '0000'에서 1을 감소시키면 어떤 결과를 얻을까? 0에서 1을 뺄 수 없으므로 '0000'앞에 저장되지 않은 1이 있다고 가정하고 뺄셈을 한다. 결과는 아래와 같이 네 자리로 표현할 수 있는 최대값이 된다.

정수형 타입이 표현할 수 잇는 최대값에 1을 더하면 최소값이 되고, 최소값에서 1을 빼면 최대값이 된다.

최대값 + 1 ➡️ 최소값
최소값 - 1 ➡️ 최대값

📍 부호있는 정수의 오버플로우

부호 없는 정수와 부호있는 정수는 표현범위 즉, 최대값과 최소값이 다르기 때문에 오버플로우가 발생하는 시점이 다르다. 부호없는 정수는 2진수로 '0000'이 될 때 오버플로우가 발생하고, 부호있는 정수는 부호비트가 0에서 1이 될 때 오버플로우가 발생한다.
부호없는 정수와 부호있는 정수의 오버플로우

부호없는 정수의 경우 표현범위가 '0~15'이므로 이 값이 계속 반복되고,
부호있는 정수의 경우 표현범위가 '-8~7'이므로 이 값이 무한히 반복된다.


📑 원본 자료

  • Java의 정석(3판) [남궁 성/도우출판/2016]
profile
나는 말하는 감자다
post-custom-banner

0개의 댓글