소년코딩

02.04 - 정수 (integer)

정수(integer)형 변수는 소수가 아닌 숫자(ex: -2, -1, 0, 1, 2)만 저장할 수 있는 변수다. C++ 에는 다섯 가지 기본 정수 자료형이 있다.

Category Type Minimum Size Note
character char 1 byte
integer short 2 bytes
int 2 bytes Typically 4 bytes on modern architectures
long 4 bytes
long long 8 bytes C99/C++11 type

char는 문자 및 정수 모두에 속하는 특수한 자료형이다.

다양한 정수 자료형 간의 주요 차이점은 크기가 다양하다는 것이다. 더 큰 정수 자료형은 더 큰 숫자를 저장할 수 있다. C++은 정수가 특정 크기를 가지지 않고 특정 최소 크기만 가질 것을 보장한다. 각 자료형의 크기는 sizeof 연산자를 사용해 알 수 있다.


정수 변수 선언하기 (Defining integers)

char c;
short int si;      // valid
short s;           // preferred
int i;
long int li;       // valid
long l;            // preferred
long long int lli; // valid
long long ll;      // preferred

short int, long int 그리고 long long int 는 유효한 정수 자료형이지만, 짧은 버전인 short, longlong long을 주로 사용한다. 접두어 int를 추가하면 입력이 늘어나고 int 자료형과 헷갈려 실수로 이어진다.


정수 범위와 부호 (Integer ranges and sign)

이전 포스트에서 n bit의 변수는 2^n 개의 다른 값을 저장할 수 있다. 정수 변수가 값을 저장할 수 있는 범위는 크기(bit)와 부호(부호가 있는지 없는지)에 따라 다르다.

부호 있는(signed) 정수는 음수와 양수를 모두 저장할 수 있는 변수다. signed 키워드를 이용해서 명시적으로 부호 있는 정수를 선언할 수 있다.

signed char c;
signed short s;
signed int i;
signed long l;
signed long long ll;

1 byte의 부호 있는 정수의 범위는 -128 ~ 127이다. 그러므로 -128에서 127 사이의 값은 1byte 부호 있는 정수 자료형에 안전하게 넣을 수 있다.

변수를 사용하여 무언가의 양이나 크기를 저장하는 경우, 음수가 필요 없다는 것을 알 수 있다. 부호 없는(unsigned) 정수는 양수 값만 가질 수 있는 정수다. unsigned 키워드를 이용해서 명시적으로 부호 없는 정수를 선언할 수 있다.

unsigned char c;
unsigned short s;
unsigned int i;
unsigned long l;
unsigned long long ll;

1 byte의 부호 없는 정수의 범위는 0 ~ 255이다. 변수를 부호 없는 것으로 선언하며 음수를 저장할 수 없지만 두 배의 양수를 저장할 수 있다.

Size/Type Range
1 byte signed -128 to 127
1 byte unsigned 0 to 255
2 byte signed -32,768 to 32,767
2 byte unsigned 0 to 65,535
4 byte signed -2,147,483,648 to 2,147,483,647
4 byte unsigned 0 to 4,294,967,295
8 byte signed -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
8 byte unsigned 0 to 18,446,744,073,709,551,615

수학적으로 n bit 부호 변수의 범위는 -(2 ^ (n-1)) ~ 2^(n-1)-1이다. n bit의 부호 없는 변수의 범위는 0 ~ 2^n - 1이다.


Overflow

자료형의 범위를 벗어나는 숫자를 변수에 넣으려고 하면 어떻게 될까? 변수가 값을 저장하기에 충분한 메모리를 할당하지 않아 비트가 손실되면 오버플로(overflow)가 발생한다.

2 진수(binary)에서 각 숫자가 0 또는 1의 값만 가질 수 있다. 아래 그림은 0에서 15까지를 보여준다.

Decimal Value Binary Value
0 0
1 1
2 10
3 11
4 100
5 101
6 110
7 111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111

보다시피 큰 숫자일수록 더 많은 bit를 나타낸다. 변수는 고정된 비트 수를 가지고 있으므로, 데이터를 저장하는데에 한계가 있다.

4 bit만 저장할 수 있는 가상의 부호 없는 변수를 생각해보자. 위의 표에 열거된 이진수 값들은 모두 4 bit보다 크지 않기 때문에 변수에 편안하게 할당된다.

그러나 변수에 4 bit를 초과하는 값을 할당하려고 하면 오버플로가 발생한다. 최하위 bit 4개만 저장하고 초과 비트는 손실된다.

예를 들어, 4 bit 변수에 10진수 값 21을 넣으려고 하면:
Decimal Value Binary Value
21 10101

21은 5 비트 '10101'이다. 4개의 오른쪽 비트 '0101'이 변수에 들어가고 가장 왼쪽 비트 '1'은 손실된다. 결국에 변수에 10 진수 값인 5('0101')가 저장된다.

실제 코드가 사용된 예제:
#include <iostream>

int main()
{
    unsigned short x = 65535; // largest 16-bit unsigned value possible
    std::cout << "x was: " << x << std::endl;
    x = x + 1; // 65536 is out of our range -- we get overflow because x can't hold 17 bits
    std::cout << "x is now: " << x << std::endl;
    return 0;
}

// x was: 65535
// x is now: 0

unsigned short 자료형의 범위는 0 ~ 65,535다. 65,535는 부호 없는 2byte(16 - bit) 정수가 보유할 수 있는 최대값이다. 값에 1을 더하면 새로운 값 65,536이 되어야 하지만 65,536은 17 비트인 '1 0000 0000 0000 0000'로 표현된다. 결과적으로 최상위 비트 '1'이 손실되고 하위 16 비트 '0000 0000 0000 000'인 숫자 0이 할당된다.

오버플로를 반대로 할 수도 있다.
#include <iostream>

int main()
{
    unsigned short x = 0; // smallest 2-byte unsigned value possible
    std::cout << "x was: " << x << std::endl;
    x = x - 1; // overflow!
    std::cout << "x is now: " << x << std::endl;
    return 0;
}

// x was: 0
// x is now: 65535

오버플로(overflow)는 정보가 손실되는 결과를 낳기 때문에 심각한 문제다. 변수가 범위를 벗어나는 갑을 저장해야 필요가 있는 경우 범위가 더 큰 변수를 사용해야 한다.


정수 나누기 (Integer division)

두 개의 정수를 나눌 때, C++은 결과가 정수라고 예상한다.

#include <iostream>

int main()
{
    std::cout << 20 / 4;
    return 0;
}

// 5

그러므로 결과가 소수라면 문제가 생긴다.

#include <iostream>

int main()
{
    std::cout << 8 / 5;
    return 0;
}

// 1

8/5의 정확한 결과는 1.6이지만 소수부(0.6)가 삭제되고 1의 결과가 나온다.

두 개의 정수로 나눗셈하면 C++은 정수 결과를 생성한다. 정수는 분수 값을 가질 수 없으므로 분수 부분은 반올림 하지 않고 단순히 떨어뜨린다.

정수 나누기를 사용할 때는 결과의 소수 부분이 손실되므로 주의해야 한다.


cpp 이 포스트의 원문은 http://www.learncpp.com/cpp-tutorial/24-integers/ 입니다.

댓글 로드 중…

블로그 정보

소년코딩 - 소년코딩

소년코딩, 자바스크립트, C++, 물리, 게임 코딩 이야기

최근에 게시된 이야기