컴퓨터/C_Programing

비트연산자(&, |, ~, <<, >>)

김치부침개21 2016. 1. 17. 23:10
반응형

 

출처 : http://cky5122.blog.me/80186222780

1. C언어 

: 비트 연산자 01 

 

 

[1] C언어 비트 연산자 

: 최적화 시키는 데 유용한 녀석들? 

 

ⓐ : 예제 01 

오늘은 예제가 조금 많을 겁니다. 후후.

비트 연산자로 할 수 있는 것들이 좀 되니..

이 참에 제대로 알아봅시다.

자. 실행 결과는 어떻게 될까요?

일단 저는 8bit 바이트, 4바이트 워드, 정수형은

2의 보수로 표현이 되고, ASCII 문자 코드를 갖는다고

가정하고 설명을 할 겁니다.

자. 50과 15를 2진수로 바꿔봅시다.

여기까지는 쉽게 이해 되실 거예요. 

5번째 줄의 a&b를 봅시다.  

 

&은 비트 AND 연산입니다. 

비트 단위로 AND 연산을 하라는 것이죠. 

 

& 연산자를 쓰면요.  

두 비트의 값이 모두 참일 때 1이고  

아닌 경우 0이 됩니다. 

 

즉 1&1일 때만 1이고 나머지 경우에 대해서는 

모두 0이라는 소리지요. 

 

이 녀석, masking 연산에 많이 쓰입니다. 

흔히 마스크 연산이라고 많이 하죠? 

다음 시간에 풍부한 예제로 알아볼 겁니다. 

 

 

따라서 결과 값은 3이 나오겠지요. 

이제 비트 OR 연산을 알아봅시다. 

 

 

6번째 줄을 보세요. 

비트 OR은 뭐겠어요?  

어느 한 쪽이라도 1이면 1이죠?  

두 개 다 0일 때만 0입니다. 

 

 

| 연산자까지 이해 가시나요? 

| 연산자가 비트 OR 연산자입니다. 

음.. 이해 가실 거라고 믿습니다. 하핫.

7번째 줄을 봅시다.

a^b네요. 이게 무엇이느냐.

배타적 OR 연산자 입니다.  

XOR 연산자요. 

두 비트의 값이 다를 때만 1이 됩니다.

그러면 만약에 1^1이면 어떻게 되겠습니까?

당연히 0이 되겠죠.  

두 비트의 값이 같으니까요. 

61이 나오겠군요?

^연산자까지 이해가 되셨나요?

 

자. 결과값이 나온 61에서 ^연산자를 1번 더 쓰죠.

우리는 이 결과에 주목할 필요가 있습니다.

32bit로 표현이 될 수 있는 모든 수에 대해서

k^a^a = k가 나온다는 사실 말이지요.

이 성질을 이용해서  

간단한 암호 프로그램도 만들 수 있고요. 

부분 반전에도 쓰이지요. 

 

물론 암호 프로그램 만들려면.. 

해싱 기법이라고 따로 있긴 합니다. 

왜냐. 어떤 비트하고 1하고 ^연산을 하면

어떤 비트가 반전이 되거든요.

0^1=1이고

1^1=0이잖아요?

부분 반전에 꽤나 쓰는 녀석입니다.

8번째 줄을 봅시다.

~연산자는 비트 전체 반전입니다.

음수를 표현하는 방법 쯤은 다들 아실 겁니다.

절대값은 항상 양수니까 절대 2진수를 먼저 구해서

비트 토글을 한 다음에

1을 더하면 되지요?

한 마디로 토글 연산자라고  

생각하심 되겠습니다. 

비트 NOT 연산자네요?

9번째 줄과 10번째 줄을 보세요.

a>>1은 한 비트만큼 오른쪽으로 이동하라는 명령이고

b<<1은 한 비트만큼 왼쪽으로 이동하라는 명령어죠.

이것만 봐선 모르실 듯 하니

한 번 볼까요?

a>>1의 실행 결과입니다.

그런데 제가 밑에 이렇게 써놨습니다.

오른쪽으로 비트 이동을 시킬 때

상위 비트가 무슨 수로 채워질 지 모른다고요.

따라서, 이런 경우는 조금 조심을 해야 겠지요? 

부호 비트를 쓰지 않는 unsigned형에다가 쓰는 것이 

그나마 좀 적절한 방안일 듯 싶습니다. 

 

자. 그러면 a>>2를 하면요? 

a를 비트 단위로 오른쪽으로 2칸 이동시키는 거죠? 

 

 

반대로 <<은요? 

왼쪽으로 비트 이동을 하라는 것입니다. 

 

b가 15였으니까 

b<<1은 30이 되겠군요. 

 

즉 >>n은 2의 n승을  

나눈 효과를  

<<n은 2의 n승을  

곱한 효과를 내겠지요. 

 

각각 왼쪽으로 비트를 n만치 이동 

오른쪽으로 비트를 n만치  

이동시키라는 겁니다.  

 

 

실행 결과입니다. 

제대로 잘 나왔나요? 

 

 

ⓑ : 예제 02

오늘은 딱 예제 3개만 보겠습니다.

짝수, 홀수 판별하는 예제입니다.

사실 우리는 짝수와 홀수 판별할 때

a%2의 값을 가지고 판별을 합니다.

 

하지만 나머지, 나눗셈 연산이

무지 오래 걸립니다. 다른 연산에 비해서요.

 

그러면 조금 더 최적화 시킬 수 있는 방법이 없을까요?

바로 비트 연산자를 이용하는 겁니다.

 

이런 아이디어를 가지고요.

 

자. x에 어떤 숫자가 오든지 간에

and 연산을 하면 최상위 비트부터

모두 0이 나올 겁니다. 맞아요?

 

물론 최하위 비트 빼고요.

자. y와 1을 AND 연산하면 뭘까요?

y가 1이면 1이 되고

그렇지 않으면 0이 되겠지요. 맞아요?

 

즉 n이 짝수라면 y값이 0이니까

n&1의 값은 0이 나올 테고요.

 

만약에 n이 홀수라면 y값이 1이니까

n&1의 값은 1이 되겠지요.

 

이번엔 이 예제를 봅시다.

a를 b로 나눈 나머지와 몫을 구하라고 합니다.

어떻게 구하면 될까요?

 

물론 b는 2의 n승 꼴로 나타낼 수 있는 수입니다.

단 n은 0 이상의 정수 정도 되겠지요.

 

ㅎㅎ; 나머지는 회색 부분이고

몫은 하얀색 부분이지요?

 

물론 n은 31보다 작거나 같은 수라고 하죠.

맞아요?

 

그러면 어떻게 구하면 되겠습니까?

나머지 구하는 것은

 

나머지를 구할 수에다가 & 2의 n승 -1

만큼 해주면 되지 않겠습니까?

 

그리고 몫 구하는 것은

비트 연산자 >>을 쓰면 될 겁니다.

오른쪽으로 n비트 만큼 이동하면 되겠죠.

 

이것이 그 코드입니다.

499를 8로 나눈 나머지와 몫을 구하는 것이죠.

 

사실 이런 비트 연산자 하나 잘 쓰는 것이

최적화를 시키는 데 매우 중요한 역할을 하지요.

아. 맞다. 제가 예제에서 뭐라 그랬었나요?

 

이 소리 했었죠?

이 상황을 조금이나마 방지하기 위해서

>>> 연산자가 있다고는 합니다만..

 

아마 C에는 없을 겁니다.

JAVA에는 있을 지도 모르겠지만 C에는 없어요.

 

그냥 이런 상황 방지를 하시려면

unsigned int형으로 선언하는 수밖에 없어요.

 

오늘 비트 연산자에 대해서

조금 훑어봤는데요.

 

비트 필드라던지, 리틀 & 빅 엔디안 같은 경우

구조체 필드에 대한 이해가 필요하므로

일단 오늘은 이렇게 간단한 것들만

먼저 알고 지나가 봅시다.

 

 

ⓓ : 숙제

숙제 드리겠습니다.

여러분이 for문 같은 반복문을 배우지 않은 듯 하니..

제가 충분히 주석을 달았고요.

 

이 프로그램에 적당한 값을 채워서

비트열을 출력해 주는 프로그램을 만들어 보세요.

 

자. 이번에는 제가 설명한 바와 같이

i를 2^n으로 나누었을 때

나누어 떨어지는 지 알아보는 프로그램을

비트 연산을 이용해서 작성해 보세요. 

 

오늘은 6가지 비트 연산자 

&, |, ^, ~, >>, << 에 대해서 배웠습니다. 

각각 비트 단위 AND, 비트 단위 OR 

비트 단위 XOR, 비트 단위 NOT 

왼쪽으로 n비트 만큼 이동 

오른쪽으로 n비트 만큼 이동이였지요. 

 

지금 이것을 다 모르셔도 괜찮습니다. 

하지만, 조금이라도  

코드 최적화를 시키시려면 

 

비트 연산자 정도는 

아시고 넘어가시면  

꽤 큰 도움이 될 겁니다. 

 


반응형