23.1 비트 AND, OR, XOR 연산자 사용하기

이제 비트 연산자를 사용하여 값을 계산해보겠습니다. 다음 내용을 소스 코드 편집 창에 입력한 뒤 실행해보세요.

  • a & b
  • a | b
  • a ^ b

bitwise_and_or_xor_operator.c

#include <stdio.h>
 
int main()
{
    unsigned char num1 = 1;    // 0000 0001
    unsigned char num2 = 3;    // 0000 0011
 
    printf("%d\n", num1 & num2);    // 0000 0001: 01과 11을 비트 AND하면 01이 됨
    printf("%d\n", num1 | num2);    // 0000 0011: 01과 11을 비트 OR하면 11이 됨
    printf("%d\n", num1 ^ num2);    // 0000 0010: 01과 11을 비트 XOR하면 10이 됨
 
    return 0;
}

실행 결과

1
3
2

각 줄에 해당 값의 10진수와 2진수(비트)를 적어놓았습니다. unsigned char 자료형에 1을 할당했을 때 비트로 표현하면 0000 0001입니다. 마찬가지로 30000 0011입니다.

앞으로 프로그래밍 분야에서 일하고자 한다면 10진수를 2진수(비트)로 표현하는 방법을 익히는 것이 좋습니다('36.9 배열을 활용하여 10진수를 2진수로 변환하기', '부록 9. 10진수 - 16진수 - 2진수 변환표' 참조).

아직 2진수로 표현하는 방법에 익숙하지 않을 때는 Windows의 계산기를 활용하면 편리합니다. 계산기를 실행하고 보기(V) > 프로그래머용(P)을 선택하면 다음과 같이 10진수를 2진수로 출력해줍니다.

그림 23‑1계산기로 10진수를 2진수로 출력

그림 23‑1에서는 10진수 3을 입력하였고 아래 부분에 2진수로 0011이 출력되었습니다. 각자 다른 숫자를 넣어서 2진수로 출력해보세요.

먼저 &, |, ^ 연산자로 각 비트를 연산했을 때의 결과(진리표)는 다음과 같습니다. 진리표의 내용이 많아 보여도 각 연산자의 특성만 이해하면 진리표 전체를 외우지 않아도 됩니다.

표 23‑2 &, |, ^ 연산 결과
연산자 비트1 비트2 결과
& 0 0 0
0 1 0
1 0 0
1 1 1
| 0 0 0
0 1 1
1 0 1
1 1 1
^ 0 0 0
0 1 1
1 0 1
1 1 0

비트 연산은 두 값을 비트 단위로 나열한 뒤 각 자릿수를 비트 연산자로 연산합니다. 각 자릿수의 연산은 독립적이며 다른 자릿수에 영향을 주지 않습니다. 그리고 비트 단위로 연산한 각 자릿수를 모두 모으면 최종 결과가 됩니다.

& 연산자는 비트 AND이므로 두 비트가 모두 1일 때 1입니다. 따라서 하나라도 0이면 0이 나옵니다. 즉, 0000 00010000 0011을 비트 AND 연산했을 때 0 & 10 그리고 1 & 11이 나오므로 0000 0001이 됩니다. 10진수로 표현하면 1 & 3은 1이 되겠죠?

그림 23‑2 비트 단위 연산

만약 120 & 26을 연산하면 어떻게 될까요?

0111 1000(120)
0001 1010(26)
_________ &
0001 1000(24)

0001 1000이 나오므로 10진수로 24가 됩니다.

| 연산자는 비트 OR이므로 두 비트 중 하나만 1이라도 1입니다. 따라서 두 비트가 모두 0일 때만 0입니다. 즉, 0000 00010000 0011을 비트 OR 연산했을 때 0 | 11 그리고 1 | 11이 나오므로 0000 0011이 됩니다. 10진수로 표현하면 1 | 33입니다.

0000 0001(1)
0000 0011(3)
_________ |
0000 0011(3)

^ 연산자는 비트 XOR이므로 두 비트가 다를 때 1입니다. 따라서 11일 때, 00일 때는 모두 0입니다. 즉, 0000 00010000 0011을 비트 XOR 연산했을 때 0 ^ 11 그리고 1 ^ 10이 나오므로 0000 0010이 됩니다. 10진수로 표현하면 1 ^ 32입니다.

0000 0001(1)
0000 0011(3)
_________ ^
0000 0010(2)