본문 바로가기

프로그래밍/C Lang

C언어 강좌 :: 07. 자료형 - 수 체계 -


06. 자료형 :: 수 체계




목차

Ⅰ.경우의 수

Ⅱ.정수

Ⅲ.오버플로우

Ⅳ.실수

Ⅴ.문자



/* main.c */


#include <stdio.h>


int main()

{

int x = 128;

char y = x;


printf("y : %d\n",y);


return 0;

}





데이터가 컴퓨터 내부에서 사용되기 위해선 메모리라는 물리적 공간에 비트 패턴으로 표현되어야 합니다. 1과 0으로 구성되는 비트 패턴은 어떻게 해석되느냐에 따라 '수'를 나타낼 수 있고 '문자'를 나타낼 수도 있습니다. 이러한 기준을 정하는 것이 바로 자료형의 역할입니다.




Ⅰ. 경우의 수


비트는 1과 0을 표현할 수 있는 단위입니다. 단일 비트로는 의미가 없지만 비트들이 모이게되면 데이터를 표현할 수 있는 기준을 정할 수 있습니다. 2비트로 표현할 수 있는 모든 경우의 수를 따져보겠습니다.



2비트로 표현할 수 있는 모든 경우의 수는 00 , 01 , 10 , 11 총 4가지입니다. 경우의 수에 관해 조금이라도 공부해보신 분들이라면 쉽게 받아들일 수 있는 내용입니다. 각각의 비트들은 0과 1 두가지 경우를 표현할 수 있으므로 n개의 비트는 총 2의 n승만큼의 경우를 표현할 수 있습니다.


다시 돌아와서 , 2비트로 표현되는 4가지 경우에 사람의 상태라는 의미를 부여해보겠습니다. 


 00 = 숙면

 01 = 식사

 10 = 공부

 11 = 청소


이런 식으로 여러 비트로 표현되는 비트패턴에 의미를 부여해 줄 수 있습니다. 그 역할을 하는 것이 자료형입니다.




Ⅱ 정수


컴퓨터가 비트패턴을 정수로 해석하는 일은 어려운 일이 아닙니다. 애초에 비트패턴은 1과 0으로 이루어져 있어서 이진수라고 생각해버리면 그만이기 때문입니다. 그러나 음의 정수를 표현하는 데에 문제가 발생합니다. 부호를 숫자로 표현할 수 없기때문입니다. 이러한 문제를 해결하기에 앞서 양의 정수부터 생각해보겠습니다.



양의 정수


양의 정수는 너무나도 간단합니다. 비트패턴을 이진수처럼 해석합니다.


우리가 배웠던 기본 자료형은 음수까지 표현할 수 있는 자료형입니다. 만약 양의 정수만을 위한 자료형으로 사용하고 싶다면 자료형 앞에 unsigned 키워드를 붙여주어야 합니다.


unsigned int x;


unsigned int형 변수는 32bit가 양의 정수를 표현하는데 사용됩니다. 따라서 음수값을 표현할 수 없습니다. 




음의 정수


프로그래밍을 하면서 음수를 사용하지 않는다는 것은 있을 수 없습니다. 컴퓨터 과학자들은 음수를 표현하기 위하여 맨 왼쪽비트를 부호비트로 사용하기로 약속했습니다. 만약 부호비트가 1이라면 그 데이터는 음수이며 , 그렇지 않다면 양수라는 얘기입니다.



부호비트를 이용하여 음수로 표현하는 것까지는 좋았는데 두번째문제가 발생합니다. 음수의 크기를 어떻게 표현할 것인가에 대한 문제입니다. 그림에 적혀있듯이 3가지 방식이 존재하는데 결론부터 말하자면 대부분의 컴퓨터는 2의 보수 표현법을 사용합니다. 2의 보수표현법은 역원의 성질을 이용한 표현법입니다. 역원이란 더했을 때 0이 되는 값을 의미합니다.



비트 연산에서 역원을 만드는 핵심은 더했을 때 버려지는 비트를 제외한 나머지를 전부 0으로 만드는 것입니다. 2의 보수 표현법에서 역원을 쉽게 구하는 방법은 비트를 전부 반전시킨 후 1을 더하는 것입니다.




Ⅲ. 오버플로우


오버플로우란 데이터가 넘쳐흐르는 현상을 뜻합니다. 데이터는 제한된 메모리를 할당받기 때문에 그 표현의 범위또한 제한받게 됩니다. 만약 그 제한된 표현범위를 넘어가면 엉뚱한 결괏값이 나타나게 되는데 그러한 상황을 "오버플로우가 발생했다"라고 부릅니다. 다음은 오버플로우가 발생하는 상황입니다.



 char x = 127;

 x = x + 1;

 printf("x : %d\n",x);


제한된 메모리를 할당받는 변수의 특성상 표현의 범위도 제한됩니다. 그 범위를 넘어가게 되면 의도치않은 결과를 얻을 수 있기 때문에 항상 이러한 문제에 대해 염두하고 있어야 합니다.





Ⅳ. 실수


컴퓨터가 실수를 표현하는 방법은 크게 고정소수점 방식과 부동소수점 방식이 있습니다. 고정소수점 방식은 소수점을 고정해놓고 정수와 실수부분을 각각 표현해주는 방식이며, 부동소수점 방식은 소수점이 이동하는 방식입니다. 결론부터 얘기하자면 고정소수점 방식은 쓰이지 않고 , 부동소수점 방식을 사용합니다.


부동소수점 방식은 굉장히 복잡한 식과 함께 사용됩니다.


지수부분과 가수부분은 아래와 같이 



우리는 왜 이렇게 복잡한 방정식에 의해 실수가 표현되는지 알 필요가 전혀 없습니다. 우리가 꼭 알고있어야 하는 것은 컴퓨터는 실수를 근삿값으로 다룬다는 점과 자료형의 메모리 크기가 클수록 더 정확한 실수의 값을 표현할 수 있다는 점입니다.


 float 소숫점이하 6자리까지 정확

 double 소숫점이하 15자리까지 정확


다음은 0.1을 100번 더한 값을 출력하는 예시 코드입니다.


 float x = 0.1;

 float sum = 0;

 for(int i = 0;i<100;i++)

    sum += x;

 printf("sum : %d\n",sum);


0.1을 100번 더한 값은 10임이 자명합니다. 그러나 실제 계산결과는 10이 아님을 확인할 수 있습니다. 그 이유는 근삿값으로 표현되는 실수의 특성때문입니다. 이러한 문제가 발생할 수 있다는 것을 항상 염두해야 합니다.





Ⅴ. 문자



컴퓨터에서 문자를 표현하는 방법은 각 문자에 숫자를 매기는 것입니다. 어떠한 문자들을 어떠한 순서로 정리할 지에 따라 아스키코드, 유니코드등 다양한 규칙이 존재합니다. 보통 영어만을 사용할 때는 아스키코드를 사용하고 그 외의 언어를 섞어쓴다면 유니코드를 사용합니다. 아래는 아스키코드표입니다. 각각의 문자들은 각각 0부터 127까지의 숫자중 하나를 부여받았습니다.



-ASCII TABLE-



아스키 코드에 정의된 문자는 총 128가지입니다. 이 수는 2의 7승이며 즉, 7비트로 전부 표현할 수 있다는 얘기입니다. 따라서 아스키코드를 저장할 때 우리는 굳이 2바이트이상을 쓸 필요가 없기 때문에 char형으로 저장하게 되는 것입니다.


마찬가지로 유니코드와 같은 경우는 더 많은 문자들을 숫자에 정의해두었기 때문에 가짓수가 클 수 밖에 없습니다. 유니코드에는 한국어를 포함해 많은 언어들이 정의되어있습니다. 이러한 유니코드는 2바이트의 저장공간을 필요로 하기때문에 short형으로 저장하게 됩니다.








ㆍ생각하기...01


#include <stdio.h>


int main()

{

int x = 128;

char y = x;


printf("%d\n",y);


return 0;

}


Q. char형은 몇가지의 수를 표현할 수 있나요?

2의 8승, 256가지

Q. 출력되는 값이 128이 아닌 이유는 무엇인가요?

char형은 -128~127의 수만 표현할 수 있기 때문에




ㆍ생각하기...02


#include <stdio.h>

{

float z = 0.1;

float sum = 0;


for(int i = 0; i<100; i++)

sum = sum + z;


printf("%f\n",sum);


return 0;

}


위는 변수 z의 값을 sum이라는 변수에 100번 더한 후 sum의 값을 출력하는 코드입니다. 0.1를 100번 더하면 sum의 값은 10이 되어야 하는데 출력되는 값은 10이 아닙니다.


Q. sum의 값이 10이 아닌 이유는 무엇인가요?

컴퓨터는 실수를 근삿값으로 나타내기 때문에 정확하지 않다.