본문 바로가기

Programming/C언어 초급

C언어 초급) 02.변수 : 03. 정수형

들어가며...

대부분의 프로그래밍 언어에서 문자열과 함께 가장 많이 사용되는 변수타입은 아무래도 정수형일 것입니다. 직관적인 숫자의 표현이기에 사용하기도 편합니다. 다만, 표현할 수 있는 범위(자료형의 크기)에 대한 이해가 반드시 되어야 합니다. 내가 구현하고자 하는 대상의 최대 또는 최소 개수를 확인하고 그 범위를 표현할 수 있는 타입을 사용하여야 할 것입니다.

이번 글에서는 정수형 타입의 종류와 크기, 이전 포스팅에서 잠시 언급하였던 C언어에서의 음수표현 방법에 대해 살펴보도록 하겠습니다.

 

  • Table of Contents
    • 정수형의 종류 및 길이
    • 문자형 타입을 통한 숫자의 범위 설명
    • 음수의 표현

정수형의 종류 및 길이

리얼 세계에서 정수의 표현은 무한합니다. 하지만 연산 및 메모리에 한계가 있는 컴퓨터 세상에서는 무한한 수의 표현은 불가능합니다. 하여 정수형 타입의 변수에는 각각 그 크기가 정해져 있습니다. 따라서, 사용하고자 하는 변수타입이 표현할 수 있는 범위 밖의 수를 할당하면 본인이 원하지 않는 결과를 초래하게되며 심할 경우 다른 메모리영역을 침범하여 프로그램이 멈추게 될 수도 있습니다.

 

모든 프로그래밍 언어에서 변수를 사용할 경우 반드시 해당 자료형의 크기를 숙지하시기 바랍니다. 특정 자료형은 OS의 종류 및 몇비트(16, 32, 64) 운영체제냐에 따라 자료형의 크기가 변하므로 반드시 개발하는 머신에 맞게 또는 여러 머신에서 사용하여도 문제가 없을 적절한 자료형을 선택하는 것이 중요합니다.

● 정수형 변수의 종류 및 크기

타입 크기(바이트) 표현범위
short 2   -32768 ~ 32767
int 4   -2147483648 ~ 2147483647
long 4(32비트) or 8(64비트)   -9223372036854775808 ~ 9223372036854775807
unsigned short 2   0 ~ 65535
unsigned int 4   0 ~ 4294967295
unsigned long 4(32비트) or 8(64비트)   0 ~ 18446744073709551615

실제 위와 같은 크기와 범위를 갖는 지 아래의 코드를 본인의 컴퓨터에서 실행해봅시다.

 

● 예제코드

#include <stdio.h>
#include <math.h>

/**
 Main 함수
 */
int main(void) {
   // 변수의 크기 저장
    short short_size = sizeof(short);
    short int_size = sizeof(int);
    short long_size = sizeof(long);
    // 각 변수타입의 max, min 값을 구한다.
    short short_max = (unsigned short)pow(2, (short_size * 8) - 1) - 1;
    short short_min = -(short_max + 1);
    int int_max = (unsigned int)pow(2, (int_size * 8) - 1) - 1;
    int int_min = -(int_max + 1);
    long long_max = (unsigned long)pow(2, (long_size * 8) - 1) - 1;
    long long_min = -(long_max + 1);
    
    printf("The size of short : %d\n", short_size);
    printf("The size of int : %d\n", int_size);
    printf("The size of long : %d\n", long_size);
    printf("The range of short : %hd ~ %hd\n", short_min, short_max);
    printf("The range of int : %d ~ %d\n", int_min, int_max);
    printf("The range of long : %ld ~ %ld\n", long_min, long_max);
    printf("The range of unsigned short : %d ~ %u\n", 0, (unsigned short)-1);
    printf("The range of unsigned int : %d ~ %u\n", 0, (unsigned int)-1l);
    printf("The range of unsigned long : %d ~ %lu\n", 0, (unsigned long)-1l);
    
    return 0;
}

 

● 결과확인

 

위의 코드를 이해하려면 이전에 잠시 언급했던 2진수, 16진수에 대한 이해가 필요합니다. 간단하게 문자형 변수를 예로 들어 숫자의 할당이 메모리에 어떻게 표현 저장되는 지 설명하도록 하겠습니다.

문자형 타입을 통한 숫자의 범위 설명

문자는 1바이트의 크기를 가지며 1바이트는 8비트입니다. 문자도 1바이트 크기의 정수형이라 가정하면 어느 숫자까지 표현할 수 있을까요?

일단 부호가 없는(unsigned) 숫자일 경우를 생각해보면 8비트까지 표현할 수 있으므로 2^8(2의 8승)의 수를 표현할 수 있습니다. 2의 8승은 256입니다만 그렇다고 256까지 표현할 수는 없습니다. 이유는 0이 포함되어져 있기 때문입니다. 따라서, 1바이트 정수형은 0 ~ 255(256 -1)까지의 수를 표현할 수 있습니다. 이해가 되셨나요? 이를 이진수로 풀어보면 아래와 같을 것입니다.

● 부호가 없는 수의 가장 큰 수, 가장 작은 수

위의 예는 부호가 없을 경우(unsigned)의 예입니다. 그렇다면 일반적으로 사용하게 되는 부호있는 정수일 경우의 표현 범위는 어떻게 구할 수 있을까요?

이를 위와 같이 설명하려면 아래에서 설명할 프로그래밍 언어에서의 음수 표현에 대한 설명이 선행되어야 합니다. 이를 위해 여기에서는 "절대값 표현"을 통한 음수표현 방법으로 1바이트 부호 있는 정수의 범위값에 대해 설명해보겠습니다.

● 부호가 있는 수의 가장 큰 수, 가장 작은 수

위의 결과에서 이상한 점을 발견하셨는지요? 네, 맞습니다. 부호비트 1비트와 나머지 7비트를 직관적으로 표현하면 위의 그림처럼 1바이트 정수는 -127 ~ 127까지 표현할 수 있습니다. 다만, 0이 중복되고 있다는 것을 눈치 채셨을 겁니다.

위와 같은 방법으로 음수를 표현하는 방식을 "절대값 표현" 이라고 합니다. 아래에서 설명하겠지만 이러한 0의 중복을 막기 위해 대부분의 시스템에서는 "2의 보수"법을 사용합니다. 2의 보수법으로 표현하게 되면 음수의 범위를 -1 ~ -128 표현할 수 있어 현재는 1바이트 정수의 값 표현 범위는 -128 ~ 127이 됩니다.

음수의 표현

프로그래밍 언어에서 음수의 표현은 어떻게 하는 걸까요? 크게 "절대값 표현", "1의 보수", "2의 보수" 로 3개의 방법이 있으며 대부분의 시스템에서는 이중 "2의 보수" 방법을 사용하고 있습니다.

이 중 "절대값 표현"방식은 위에서 설명하였으므로 이번 장에서는 "1의 보수", "2의 보수" 방법에 대해서 살펴보도록 하겠습니다.

● 1의 보수를 사용한 음수 표현

1의 보수 방법은 양수의 값에서 모든 비트 값을 반전시켜 음수를 표현하는 방법입니다. 아래 그림을 보시면 이해되시리라 생각됩니다.

이또한 0과 -0이 존재하기 때문에 -127 ~ 127 까지 표현되는 문제점이 있습니다. 이를 보강한 방법이 2의 보수 방법입니다.

● 2의 보수를 사용한 음수 표현

2의 보수 방법은 1의 보수 방법과 같이 모든 비트를 반전시킨 후 1을 더하는 방법입니다.

위와 같이 2의 보수 방법을 사용하면 +0과 -0의 비트 값이 동일해져 동일한 0값을 사용할 수 있습니다. 또한 128의 값을 2의 보수 방법으로 표현하면 128은 unsigend 값이므로 "1000 0000"이며 비트를 반전 시키면 => "0111 1111" 에 1을 더하면 => "1000 0000" (-128)이 되게 됩니다.

이로써 2의 보수 표현식을 사용하면 1바이트 정수형 값의 범위는 -128 ~ 127까지 표현할 수 있게 되며 2바이트, 4바이트, 8바이트의 정수 변수도 동일한 방법으로 표현 범위를 예측할 수 있습니다.

마무리...

C언어의 정수 타입의 종류와 크기 및 음의 값을 표현하는 방법까지 살펴봤습니다. 위와 같이 C언어에서는 2진수, 16진수, 10진수 간의 값 변환이 자유롭게 이루어져야 디버깅 및 실제 메모리에 어떤 값이 저장되어 있는 지 를 명확하게 알 수 있습니다.

다음 포스팅에서는 실수형 변수에 대해 알아보도록 하겠습니다.

 


U2ful은 입니다. @U2ful Corp.