Developer

6.(C언어) 진법, 음수표현 본문

Programming Language/C

6.(C언어) 진법, 음수표현

DPhater 2020. 8. 1. 20:35

진법은 수를 표기하는 방법을 나타낸다. 우리가 사용하고있는 자리당 0~9의 숫자를 사용하는 것이 10진법이다. 2진법은 0과1 두가지의 숫자로만 표현하는 방법이고, 8진법은 0~7, 16진법은 0~F로 수를 표기하는 방법이다.

2진법

2진법은 0과 1만으로 수를 표현하는 방법이다. 가장 오른쪽 자리 부터 1, 2, 4, 8... 

2의 거듭승으로 표현된다.

128

64

32

16

8

4

2

1

이렇게 8자리의 2진수를 생각해 보자 각 자리의 값이 1인 수만 더해주면 해당 2진수가 10진수로 몇 인지 계산할 수 있다. 0010 1111 이라는 2진수가 있다면 10진수로 1+2+4+8+32 =47 인것을 계산할 수 있다.

반대로 10진수를 2진수로 바꿀 수도 있다. 바꾸려는 숫자를 몫이 0이 될때까지 2로 계속 나누어 주면된다. 47을 이진수로 바꾸어 보자

47/2=23 나머지 1

23/2=11 나머지 1

11/2=5 나머지 1

5/2=2 나머지 1

2/2=1 나머지 0

1/2=0 나머지 1

이제 계산된 나머지들을 가장 마지막것부터 작성하면 10 1111이라는 값이 나오고

10진수 47을 2진수로 표현하면 10 1111이라는 값이 나오는것을 확인할 수 있다.

8진법

8진법은 각 자리당 0~7까지의 숫자만 사용하는 것이다.

2진수 3자리가 0~7까지 나타낼 수 있는것을 이용해 2진수를 쉽게 8진수로 바꿀 수 있다.

0010 1111 을 가장 오른쪽부터 3자리씩 묶는다.

000,101,111 각 묶음별로 2진수를 계산한다.

0 5 7 따라서 2진수 0010 1111은 8진수로 57이 되는것을 알 수 있다.

16진법

8진법과 유사한 방법으로 2진수를 오른쪽부터 4자리씩 묶어서 계산하면 16진수가 된다. 주의할 점은 16진법은 각 자리가 0~15로 표현되는 것인데 10,11,12,13,14,15를 하나의 숫자로 표현할 수 없으므로

10은 a로 11은 b로...15는 f로 표현한다.

따라서 2진수 0010 1111은 16진수 2F가 되는것을 알 수 있다.

 

8진수와 16진수는 C에서 편하게 확인할 수 있다.

#include<stdio.h>
int main(){
	printf("10진수 : %d\n",47);
	printf("10진수 : %d\n",057);
	printf("10진수 : %d\n",0x2F);
	printf("8진수 : %o\n",47);
	printf("8진수 : %o\n",057);
	printf("8진수 : %o\n",0x2F);
	printf("16진수 : %x\n",47);
	printf("16진수 : %x\n",057);
	printf("16진수 : %x\n",0x2F);
	return 0;
}

코드1 실행 결과

10진수 47은 8진수로 57이고, 16진수로 2F인걸 앞에서 계산을 통해 알아보았다.

C에서는 8진수는 숫자 앞에 0을 써서 나타내고, 16진수는 0x를 써서 나타낸다.

10진수 : 47

8진수 : 057

16진수: 0x2F

이 숫자들을 %d(10진수 정수) 서식지정자로 출력하면 자동으로 10진수로 계산이 되어 출력되고, %o(8진수) 서식지정자로 출력하면 자동으로 8진수로 계산이 되어 출력되며, %x(16진수) 서식지정자로 출력하면 자동으로 16진수로 계산이 되어 출력된다.

자료형의 범위와 2진수

컴퓨터는 모든 데이터를 0과 1로만 표현한다. 즉 2진법으로 모든것을 표현하는 것이다. 0혹은1이 들어갈 수 있는 하나의 공간이 bit(비트) 이며 1byte는 이러한 공간이 8개가 있는 것이다.

1byte 자료형으로 unsigned char를 생각해보자 unsigned char의 범위는 0~255이다. 범위가 왜 이렇게 되는지는 아래의 표를 보면 알 수 있다.

128

64

32

16

8

4

2

1

위의 8개로 나타낼 수 있는 최솟값은 모든 곳에 0이 들어가 있는 0이 되며, 최댓값은 모든곳에 1이 들어가있는 255가 된다. 따라서 unsigned char의 범위는 0~255인 것이다.

부호있는 자료형 표현

그렇다면 부호가 있는 자료형은 비트로 어떻게 표현을 할까?바로 부호비트를 사용하는 것이다. 비트의 나열에서 가장 오른쪽 비트 즉, 가장 작은 의미를 가지는 비트를 LSB(Least significant Bit), 가장 왼쪽에 있는 비트를 즉, 가장 큰 의미를 가지는 비트를 MSB(Most Significant Bit)라고 하는데 이때 MSB를 부호 비트로 사용한다. 즉 MSB가 0이면 해당수가 양수이고, MSB가 1이면 해당수가 음수인 것이다.

그러면 MSB를 제외한 값은 어떻게 표시될까? 1byte인 자료형으로 부호비트만 이용해 음수를 표현해서 계산을 해보자. 여기에서 사용하는 2진수는 위에서 계산한 10진수 47이다.

0010 1111 : 47

1010 1111 :-47

47+(-47)은 0인데 2진수로 계산을 하면 1101 1110 로 -94라는 값이 나온다. 모든것을 2진법으로 하는 컴퓨터에게 이는 큰 문제이다.

그래서 보수를 이용하게된다. 3에대한 10의 보수는 7 , 4에대한 10의 보수는 6 이다. 즉 해당 10에서 해당 수를 뺀값, 또는 해당수와 합하여 10을 만드는 값을 해당수의 10의 보수라고 한다. 그렇다면 1의 보수란 합하여 1을 만들어 주는 수이고, 1에대한 1의보수는 0, 0에대한 1의 보수는 1이므로 2진수에 1의 보수는 0과 1을 반전시켜주는 것이다.

0010 1111 : 47

1101 0000 : -47(1의 보수 표현)

2진수 계산 결과는 1111 1111이며 이 수의 1의 보수를 취하면 원하는 값인 0이 나온다. 원하는 결과가 나왔지만 비트반전을 많이 해야하는 단점이 존재한다.

그래서 1의 보수가 아닌 2의 보수를 사용하게 된다.

2의 보수(2's complement)란 1의 보수에 1을 더해준 값이다.

0010 1111 :47

1101 0001 :2의 보수

2진수 계산 결과는 1 0000 0000가 나오는데 크기가 1byte인 char형으로 가정했기 때문에 초과한 1은 무시되고 나머지 8bit의 값인 0을 가지게 된다.

따라서 0010 1111에 2의 보수를 취한 1101 0001이 -47의 표현이다.

부호가 있는 자료형에서

MSB가 0이면 그 숫자를 그대로 읽으면 되고

MSB가 1이면 숫자를 2의 보수를 구해 앞에 -를 붙혀주면 된다.

그럼 이번에는 unsigned char의 범위가 아닌 부호가있는 signed char의 범위가 왜 -128~127인지 확인해보자.

8bit중에서 MSB는 부호비트이므로 사용할 수 없다.

따라서 양수의 최댓값은 부호 비트를 제외하고 모두 1이 들어가 있는

0111 1111 인 127이 되고,

음수일 때 표현할 수 있는 최솟값은 부호 비트를 제외하고 모두 0인

1000 0000 이고, 이를 2의 보수를 취하면 1000 0000이 되므로 128이다.

부호 비트가 1이었으므로 -128이 된다.

따라서 signed char의 범위는 -128 ~ 127이 된다.

'Programming Language > C' 카테고리의 다른 글

8.(C언어) 상수  (0) 2020.08.01
7.(C언어) 실수 자료형의 표현 방법_부동소수점  (0) 2020.08.01
5.(C언어) 자료형_문자  (0) 2020.08.01
4.(C언어) 자료형_실수  (0) 2020.08.01
3.(C언어) 자료형_정수  (0) 2020.08.01
Comments