오버플로우와 언더플로우
C언어의 자료형
C언어는 변수를 선언할 때 자료형을 함께 알려주어야 합니다.
C언어가 제공하는 정수를 표현하는 기본 자료형은 다음과 같습니다.
- char - 1byte
- short - 2bytes
- int - 4bytes
- long - 4bytes
- long long - 8bytes
자료형마다 데이터를 담을 수 있는 크기가 다르다는 것을 알 수 있죠.
오늘은 bit에 대한 개념을 바탕으로
오버플로우와 언더플로우에 대해서 설명하려고 합니다.
컴퓨터에서 데이터를 표현하는 방법
-
1byte = 8 bits
-
MSB는 signed 자료형에서 부호를 의미하는 비트
음의 정수 표현
- 컴퓨터는 음의 정수를 해당 값에 대응하는 양의 정수와 더했을 때 0이 된다는 사실을 바탕으로 표현
예를 들어, char x=-1; 이라면
이에 대응하는 양의 정수는 1이므로
0000 0001 과 더했을 때 0이 되는 수가 음의 정수가 되는거죠.
따라서, 컴퓨터는 char형 -1을 1111 1111 로 표현합니다.
오버플로우
- 선언된 자료형이 나타낼 수 있는 데이터의 크기보다 큰 데이터가 변수에 들어올 때 발생
변수를 다음과 같이 초기화해봅시다.
char x = 200;
unsigned char y = 200;
해당 변수를 출력하면 어떤 값이 나올까요?
출력결과
x를 보면 원하는 데이터 값이 아닌 엉뚱한 값이 출력된 것을 알 수 있죠?
결과분석
x와 y 모두 1100 1000 으로 데이터가 표현될 겁니다.
하지만 char는 자료형의 크기가 1바이트죠?
x의 경우 signed 자료형이기 때문에 맨 앞에 MSB는 음수를 의미하는 비트가 되는 것입니다.
그러면 표현할 수 있는 데이터의 범위는 -128~127 이 됩니다.
이때, 오버플로우가 발생합니다.
따라서, 실제 의미하는 값을 알기 위해서는 x와 더했을 때 0이 되는 양의 정수를 구하고, 음의 부호를 붙이면 되겠죠.
(사실 2의 보수를 취하는 연산이 있습니다. 하지만, 제가 생각하기에 두 수의 합이 0이 되는 조합을 찾는게 직관적으로 이해가 더 잘 됐습니다. )
-
1100 1000 => x에 저장된 데이터
-
0011 1000 => x와 더했을 때 0이 되는 데이터, 56
-
0000 0000 => 두 비트를 더했을 때, 0
따라서, x는 -56이 출력됩니다.
y는 어떨까요?
y의 경우 unsigned 자료형이기 때문에 MSB는 부호를 의미하지 않겠죠.
따라서 표현할 수 있는 데이터는 0~255 이기 때문에 문제없이 200이 출력이 되는 것입니다.
언더플로우
- 선언된 자료형이 나타낼 수 있는 데이터의 크기보다 작은 데이터가 변수에 들어올 때 발생
변수를 다음과 같이 초기화해봅시다.
char x = -10;
unsigned char y = -10;
출력결과
결과분석
x와 y 모두 1111 0110 으로 데이터가 표현될 겁니다.
(10을 나타내는 0000 1010과 합했을 때 0이 되는 수)
x의 경우 표현할 수 있는 데이터의 범위에 있으므로 문제없이 -10이 출력이 되었습니다.
y의 경우 표현할 수 있는 데이터보다 작은 값이 들어왔죠?
(unsigned 자료형은 0이상의 정수만 표현합니다.)
언더플로우가 발생했습니다.
y의 경우 MSB가 부호를 의미하지 않고 데이터 크기를 반영하게 됩니다.
따라서 해당 데이터를 246으로 처리하게 됩니다.
Leave a comment