사람들이하는 계산방식과 다르게 컴퓨터가 하는 연산에는 비트연산 이라는 것이 있어요.
비트 연산을 하기 위해서는 데이터의 저장 형태를 이해 해야합니다.
일반적으로 int 형으로 선언된 변수는 4byte 크기 입니다.
1byte 는 8bit 이므로 int 형은 32개의 bit 가 연속으로 이어진 형태 입니다.
만약 64 라는 데이터를 int 형의 변수에 저장 한다면 , 실제로 저장된 데이터는 아래와같은 형태 입니다.
00000000000000000000000001000000
이것을 보기 쉽게 바이트 단위로 나눠서 표시하면
맨 우측부터 비트자릿수 0 부터 시작 됩니다.
위에서 저장한 64 라는 정수는 실제로 6번 비트만 1인 형태로 저장됨을 알 수 있습니다.
이것을 hex 값으로 표시하면,
0x00000040 이 됩니다.
hex 값은 0~F (123456789ABCDEF) 까지 16개의 숫자로 이루어진 진수법이며, 16개는 4비트로 표현 할 수 있습니다.
그래서 위 4바이트를 hex 값으로 표시할때는 4개의 비트에 하나의 16진수 숫자로 표시할 수 있지요.
0000 0000 0000 0000 0000 0000 0100 0000
0 0 0 0 0 0 4 0
이게 비트연산이랑 무슨 상관이냐고요?
비트 연산은 이처럼 숫자를 비트로 저장된 상태에서 이루어지는 연산 입니다.
예를 들어 만약 위 값에서 유일하게 1 인 6번째 비트 값을 오른쪽으로 한칸 이동 했다고 생각해 보세요.
그럼 모든 데이터비트가 0 이고, 5만 1인 데이터의 값은 무엇일까요?
비트로 모두 표현하면
0000 0000 0000 0000 0000 0000 0010 0000
Hex 값으로 하면 0x00000020 이 됩니다.
이 값은 정수로 32에 해당 하지요.
비트를 옆으로 이동 시키는 것을 쉬프트 라고 하며, 비트 연산으로 이 값이 절반으로 떨어진 것을 알 수 있어요.
반대로 좌측으로 이동했다면 어떻게 될까요?
Hex 값으로 0x00000080 이 되고, 이 값은 정수로 128 이 됩니다.
단순히 숫자를 빼거나 더한것과는 다른 형태 임을 알 수 있지요.
이처럼 비트의 형태를 변경 하는 연산자를 비트연산자라 하고,
c 에서는 다음과 같은 비트연산을 지원 합니다.
연산자 | 기능 |
& | 비트 연산 AND ( 두 비트가 모두 1 이면 1, 아니면 0 ) |
| | 비트 연산 OR ( 두 비트중 하나라도 1 이면 1 ) |
^ | 비트 연산 XOR ( 두 비트가 다르면 1, 같으면 0 ) |
~ | 비트연산 NOT ( 비트의 상태를 반전 ) |
<< | 비트연산 Shift ( 비트를 좌측으로 이동 한다.) |
>> | 비트연산 Shift ( 비트를 우측으로 이동 한다. ) |
여기서 &와 && 를 착각 하거나 | 와 || 를 착각 하시는 경우가 있는데요.
&&와 || 는 논리 연산자며, 비트연산자가 아님을 기억 하시기 바랍니다.
이제 예제를 보면서 하나씩 연산자의 동작을 알아보겠습니다.
#include <stdio.h>
int main(void)
{
int a,b,c;
a = 0x01;
b = 0x03;
c = 0x00;
c = a&b;
printf("0x%08x & 0x%08x = 0x%08x \n",a,b,c);
return 0;
}
이 연산은 다음과 같은 연산을 합니다.
1과 3 은 0번과 1번 비트만으로 표시되며, 두 비트는 모두 0번 비트만 1 입니다.
따라서 &(AND) 연산을 하면 둘다 1 인 0 번 비트만 1 로 출력 됩니다.
| (OR) 은 어떨까요?
둘 중 하나만 1 이면 1 이 출력 되므로,
출력 값은 0번 비트와 1 번 비트가 모두 1 인 정수 3이 됩니다.
여기서 비트연산을 잘 하기 위해서는 다음 표를 머리속에 그려두시는게 좋아요.
16진수와 Binary 형태를 머리속에 딱 넣고 있으면, 비트 연산은 매우 쉬워 집니다.
| (OR) , ^ (XOR) 연산은 AND 를 이해 했다면 매우 쉽습니다.
개념적으로 AND, OR, XOR 만 이해 하고 있으면 되거든요.
그 개념을 표로 그려보면,
입니다.
디지털논리회로를 공부하면 알게 되지요.
아, 참고로 임베디드를 하고자 마음을 먹었다면 디지털논리회로를 무조건 깊게 공부하시기 바랍니다.
카운터를 설계할 수 있을 정도까지는 공부하시는게 좋아요. 많은 도움이 될겁니다.
이제 XOR 까지 했으니 ~ 을 알아볼 차례 입니다.
이것은 NOT 입니다.
위의 표에서 먼저 보여드린것과 같이 비트를 반전 하지요.
예제를 보겠습니다.
#include <stdio.h>
int main(void)
{
int a = 0x5555;
a = ~a;
printf("a = 0x%08x \n",a);
a = ~a;
printf("a = 0x%08x \n",a);
}
이 코드를 실행 하면,
a = 0xffffaaaa
a = 0x00005555
위와 같이 출력 됩니다.
먼저 숫자 5 는 비트 값으로 0101 이고 이것을 반전시키면 1010 이 되어 Hex 값은 0xA 가 됩니다.
그런데 앞의 FFFF 는 뭘까요?
네 맞아여 4바이트 정수 (int) 로 선언되었기 때문에 0x5555 는 실제로 0x00005555 가 됩니다.
따라서 이것을 반전 시키면 0 응 비트 값으로 0000 이므로 1111 이 되어 모두 f 가 됩니다.
그다음 코드에서 다시 반전 시켜 원래대로 다시 출력 되네요.
여기서 %x 는 16진수 값을 출력 하기위한 치환자 이고요, 앞에 붙은 08 은 8자리씩 출력 하라는 뜻입니다.
다음은 쉬프트 연산자 입니다.
계속..
'코딩을 합시다 > 최대한 쉽게 설명한 C 언어' 카테고리의 다른 글
초등학생도 이해하는 C 언어 - & 와 && 의 차이점 (1) | 2020.05.23 |
---|---|
초등학생도 이해하는 C 언어 - 조건 연산자 (삼항 연산자) (0) | 2020.05.07 |
초등학생도 이해하는 C 언어 - 논리 연산자 (0) | 2020.05.07 |
초등학생도 이해하는 C 언어 - 관계 연산자 (0) | 2020.05.07 |
초등학생도 이해하는 C 언어 - 증감 연산자 (0) | 2020.05.07 |
댓글