c언어 프로그래밍 비트연산자에 대하여 알아보자.(2진법, 8진법, 16진법, 10진법)

반응형

2진법 8진법 10진법 16진법

프로그래밍을 하다보면 여러분은 정수보다

2진수랑 더 친해져야한다.

필자의 경우는 3자리 정수정도는 암산으로 2진법으로 바꿔버린다.

 

일단 비트연산자로 넘어가기전에

2진법과 10진법 8진접 16진법이랑 친해져보자.

 

2진법, 10진법 변환하기

 

2진법은 0과 1로 이루어진 숫자체계

8진법은 0~7까지 이루어진 숫자체계

10진법은 우리가 아는것 처럼 0~9까지 이루어진 숫자체계이다.

 

16진수는?

9이상의 숫자가 없기에 a, b, c, d, e로 간다

a는 10

b는 11

c는 12

d는 13

e는 14

f는 15

다.

 

10진법을 2진법으로 바꾸는건

중학교때 충분히 해봤다고 믿고 패스하겠다.

(이 글을 보는 사람이 대학생이라면 2진법 변환을 모르면 부끄러운줄알자.)

 

필자의 암산법은 이렇다.

20라는 숫자가 있다(10진수)

 

2진수는 2^0

2^1

2^2

.....

2^n

 

2^0은 1이고, 2^1은 2고, 2^2는 4 , 8 16~~~~

20이라는 숫자를 만들기위해서

위에서 필요한숫자는 무엇인가?

16과 4를 더하면된다.

 

즉 2^4과 2^2이 필요하다. 2^3은 없어도되고, 2^1, 2^0은 필요없다.

고로 필요하면1, 필요없으면 0으로 나타내자

2^0은= 0

2^1은= 0

2^2은= 1

2^3은= 0

2^4은 =1

 

20을 2진법으로 나타내면 10100이다.

 

 

이걸 반대로 10진수로 나타내면 이렇다.

일의 자리에 2^0을 곱해준다.

십의 자리에 2^1을 곱해준다.

백의 자리에 2^2을 곱해준다.

천의 자리에 2^3을 곱해준다.

만의 자리에 2^4을 곱해준다.

그리고 각 수를 합쳐주면된다.

 

2^0*0 = 0

2^1*0 = 0

2^2*1 = 4

2^3*0 = 0

2^4*1 = 16

0+0+4+0+16 = 20

 

자 그럼 빠르게 응용해보자

 

78이라는 숫자를 만들기위해

 

64가 무조건 필요할꺼다.

78-64 하면 14이니

14를 어떻게만들까

8과 4와 2를 더해주면 14가 나온다.

 

즉 아까처럼 필요하면 1, 필요없으면 0

2^6(64) = 1

2^5(32) = 0

2^4(16) = 0

2^3(08) = 1

2^2(04) = 1

2^1(02) = 1

2^0(01) = 0

 

1001110

간단하지 않은가?

2진법을 만들기에 나눗셈이 약하다면

2^n을 활용해 덧셈 뺄셈으로 해도된다.

 

자 이제 16진법과 8진법을 자유롭게 만들어보자.

 

2진법을 알면 8진법과 16진법을 만들기 쉽다.

아까 모든 10진법을 2진법으로 변경해주면

8진법과 16진법으로 바꾸기 쉽다.

 

아까 78을 2진법으로 바꾸었을때 1001110이였다.

 

이걸 바로 8진법으로 바꾸는법이있다.

(10진법으로 바꾼후 8로 나눌생각이였다면 곱게접어 버려라)

 

2진법은 1bit에 1과 0이 들어갈 수 있다.

8진법은 이 1bit가 3개 있다고 생각하자. 3bit

즉 2진법은 2^1의 숫자를 표현하지만, 8진법은 2^3의 숫자를 표현 할 수 있다.

1칸과 3칸

즉 아까 만든 1001110을 칸으로 나눠볼까?

1 0 0 1 1 1 0

눈치를 채면 머리가 좋은거다.

8진법은 3칸씩 끊는다고 생각하면된다.

뒤에서부터 3개씩 끊어주자

1/001/110

맨 앞자리에 자리수가 안맞으면 0으로 채워져있다 생각하면 쉽다.

001/001/110

자 그리고 각 칸의

첫번째 자리에 2^0

두번째 자리에 2^1

세번째 자리에 2^2

을 곱한 후 더해준다.

0*2^2 + 0*2^1 + 1*2^0 / 0*2^2 + 0*2^1 + 1*2^0 / 1*2^2 + 1*2^1 + 0*2^0

1/1/6

 

78이라는 10진수는

2진수로 1001110이고

8진수로 116이다.

 

자 그렇다면 16진수는?

3자리가아니라 4자리로 끊어주면 된다.

100/1110

자 그리고 아까전에 필자가 맨 앞 칸 자리가 안맞으면 0으로 채워주라했다.

0100/1110

16진수는 2^3까지 곱해주면 되겠다.

0*2^3 + 1*2^2 + 0*2^1 + 0*2^0/1*2^3 + 1*2^2 + 1*2^1 + 0*2^0

4/14

자 아까 a는 10, b는 11, c는 12, d는 13, e는 14, f는 15라했다.

4/e

 

프로그래머용 계산기를 두둘겨볼까?

 

자 이제 비트연산자로 넘어가자.

 

비트연산자

연산자 기능정의 결합방향
& (AND) 앤드연산자 앤드연산을 수행한다. ->
| (OR) 오아 연산자* 오아 연산을 수행한다. ->
^ (XOR) 엑스오아 연산자 엑스오아 연산을 수행한다. ->
~ (NOT) 낫 연산자 낫 연산을 수행한다. <-
<< 비트 이동 연산자(왼쪽) 비트를 왼쪽열로 이동시킨다. ->
>> 비트 이동 연산자(오른쪽0 비트를 오른쪽열로 이동시킨다. ->

*오아 연산자 |는 엔터키 위에있다. Shift + \ 클릭

 

&연산자

0 & 0 = 0 반환

1 & 0 = 0 반환

0 & 1 = 0 반환

1 & 1 = 1 반환

 

프로그램 예시

#include 

int main(void) {

int i = 12;
int j = 20;

printf("AND 연산 결과 : %d\n", i & j);

return 0;
}

 

왜 4가 나왔는지

필자가 왜 위에서 2진법 공부를 시켰는지...

2진법 이해못하면 절대 못푼다.

 

12를 2진법으로 바꾸면  110이다.

20을 2진법으로 바꾸면 1100이다.

 

일단 자리수가 안맞으면 앞자리를 0으로 채우자

12를 이진법 01100

20을 이진법 10100

자 그리고 각자 자리수를 &연산한다.

01100

10100

--------

00100

이걸 10진법으로 다시바꾸면 ?

 

4

이렇게해서 4가 나온것이다.

 

|연산자

0 | 0 = 0 반환

1 | 0 = 1 반환

0 | 1 = 1 반환

1 | 1 = 1 반환

 

프로그램 예시

#include 

int main(void) {

int i = 12;
int j = 20;

printf("AND 연산 결과 : %d\n", i | j);

return 0;
}

일단 자리수가 안맞으면 앞자리를 0으로 채우자

12를 이진법 01100

20을 이진법 10100

자 그리고 각자 자리수를 &연산한다.

01100

10100

--------

11100

 

이를 10진법으로 바꾸면

16+8+4 = 24

 

^연산자

0^0 = 0 반환

1^0 = 1 반환

0^1 = 1 반환

1^1 = 0 반환

 

프로그램 예시

#include 

int main(void) {

int i = 12;
int j = 20;

printf("XOR 연산 결과 : %d\n", i^j);

return 0;
}

 

일단 자리수가 안맞으면 앞자리를 0으로 채우자

12를 이진법 01100

20을 이진법 10100

자 그리고 각자 자리수를 ^연산한다.

01100

10100

--------

11000

 

16+8 =24

 

~연산자

 

~0 = 1

~1 = 0

 

프로그래밍 예시

 

#include 

int main(void) {

int i = 12;
int j = 20;

printf("NOT 연산 결과 : %d\n", ~i);
printf("NOT 연산 결과 : %d\n", ~j);

return 0;
}

 

자 왜 이런 결과가 초례할까?

필자가 자꾸 앞자리가 모자르면 0으로 채우라했다.

자료형을 보자

int 형이다.

int형은 크기가 4byte이며, bit로 바꾸면 32bit다

12를 이진법 01100

20을 이진법 10100

정확하게 쓰면

 

00000000 / 00000000 / 00000000 / 00001100

00000000 / 00000000 / 00000000 / 00010100

 

이를 ~ 시켜버리면

11111111 / 11111111 / 11111111 / 11110011

11111111 / 11111111 / 11111111 / 11101011

 

계산할 엄두가 나나?

필자는 지금 글쓰다가 살짝 당황했다.

그래서 2의 보수를 계산법을 도입하면 간단하다.

 

2의 보수는 나중에 알려주겠다.

그냥 간단하게 내가 수행하려던 숫자에 1을 더한 후 * -1을 해주면된다.

<< >> 연산

 

2<<2 2를 2칸만큼 왼쪽으로 비트 이동한다.

21>>3 21를 3칸만큼 오른쪽으로 비트 이동한다.

 

#include 

int main(void) {

int i = 12;
int j = 20;

printf("<<연산 결과 : %d\n", i<<4);
printf(">>연산 결과 : %d\n", j>>2);

return 0;
}

 

12를 이진법 01100

20을 이진법 10100

정확하게 쓰면

 

00000000 / 00000000 / 00000000 / 00001100

00000000 / 00000000 / 00000000 / 00010100

 

12<<4 즉

0000000 / 00000000 / 00000000 / 11000000

2^7 + 2^6 = 128 + 64 = 192

 

20>>2

00000000 / 00000000 / 00000000 / 00000101

2^2+2^0 = 4+1 = 5

 

자 오늘은 2진법, 8진법, 16진법과 10진법관계를 알아보았으며,

비트이동연산자에 대하여 알아보았다.

궁금한 것들은 댓글 바란다.

댓글

Designed by JB FACTORY