오버플로우와 언더플로우

1 minute read

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으로 처리하게 됩니다.

Categories:

Updated:

Leave a comment