HOWTO · C

C에서 비트를 비교하는 방법

이 기사에서는 C에서 비트를 비교하는 방법을 보여줍니다.

이 페이지의 내용

비트 연산은 컴퓨터 프로그래밍, 특히 저수준 데이터 조작을 다룰 때 기본이 됩니다. C에서는 개별 비트나 비트 그룹을 비교하는 여러 가지 방법이 있습니다.

이 기사에서는 각 방법을 보여 주는 코드 예제와 함께 다양한 기법을 살펴보겠습니다.

C에서 비트 비교를 위해 비트 XOR 및 AND 연산을 사용하여 사용자 지정 함수 구현하기

비트 AND 연산자(&)는 두 피연산자의 대응하는 비트들 사이의 비트 단위 비교를 수행하는 데 사용됩니다. 이 연산의 결과는 두 피연산자 모두에서 대응하는 비트가 설정된 경우에만 각 비트가 설정되는 새 값이 됩니다.

예제 코드:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 & num2;

  printf("Result: %u\n", result);  // Output: 0 (Binary: 0000)

  return 0;
}

출력:

Result: 0

이 예제에서 num1과 num2는 각각 값 9와 6으로 초기화됩니다. 이 값들은 이진수로 1001과 0110으로 표현됩니다.

num1과 num2 사이의 비트 AND 연산(num1 & num2) 결과는 이진수로 0000이며, 십진수로는 0입니다. 이는 num1과 num2 모두에서 설정된 대응 비트가 없다는 것을 의미합니다.

한편, 비트 XOR 연산자(^)는 두 피연산자의 대응하는 비트들 사이의 비트 단위 비교를 수행하는 데 사용됩니다. 이 연산의 결과는 피연산자들의 대응하는 비트가 다를 경우 각 비트가 설정되는 새 값이 됩니다.

예제 코드:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 ^ num2;

  printf("Result: %u\n", result);  // Output: 9 (Binary: 1001)

  return 0;
}

출력:

Result: 15

이 예제에서 비트 XOR 연산(num1 ^ num2) 결과는 이진수로 1001이며, 십진수로는 9입니다. 이는 num1과 num2의 대응하는 비트가 다르다는 것을 의미합니다.

일반적으로 비트 비교는 단일 비트 값에 액세스하고 union 및 struct 키워드를 사용하여 비트 필드를 구현하는 것과 같은 필요한 작업을 수행하는 것을 수반합니다.

그러나 비트 연산은 숫자의 지정된 비트를 비교하는 더 효율적인 방법을 제공합니다. 이 경우 32비트 너비가 보장되는 u_int32_t 유형에 적합한 별도의 함수를 구현합니다.

아래 예제 프로그램은 명령줄 인수로 세 개의 정수를 받으며, 처음 두 개는 비교되는 숫자이고 세 번째 정수는 n번째 비트를 지정합니다. strtol을 사용하여 argv 요소를 변환하므로 반환 값을 u_int32_t 유형으로 저장할 때 일부 정밀도가 손실된다는 점에 유의하세요.

compareBits 함수는 중간 값을 저장하는 두 개의 지역 변수 mask와 tmp를 선언합니다. 1을 nth - 1 위치만큼 왼쪽으로 이동하여 mask에서 n번째 비트를 설정합니다.

그런 다음 두 사용자 입력 숫자에 XOR를 적용하여 각 위치의 비트 차이를 가져오며, 결과에 비트가 설정되어 있으면 값이 다름을 나타냅니다. 마지막으로 n번째 위치에서 비트를 추출하고 값이 0인지 확인해야 합니다.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask, tmp;

  mask = 1 << (nth - 1);
  tmp = n1 ^ n2;

  if ((tmp & mask) == 0)
    return true;
  else
    return false;
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

샘플 파일 형식:

./main 1234 1231 1

입력 파일 형식:

bits not equal!

예를 들어, 정수 1234와 1231은 이진수로 각각 00000000000000000000010011010010과 00000000000000000000010011001111로 표현됩니다.

따라서 이 두 수에 XOR를 적용하면 이진수 표현 00000000000000000000000000011101이 되며, 최종적으로 마스크 00000000000000000000000000000010과 AND를 적용하여 단일 비트 위치 값을 추출합니다. 결과가 모두 0이면 비교된 비트가 같다는 것을 의미하고, 그렇지 않으면 그 반대입니다.

또는 아래 예제 코드와 같이 compareBits 함수를 줄이고 XOR/AND 연산을 return 문으로 옮길 수도 있습니다. 호출 함수에서 ? : 삼항 연산자를 사용하여 해당 메시지를 출력하므로, 이 함수는 비트 XOR/AND 연산의 논리적 반대를 반환한다는 점에 유의하세요.

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
  u_int32_t mask;

  mask = 1 << (nth - 1);

  return !((n1 ^ n2) & mask);
}

int main(int argc, char *argv[]) {
  u_int32_t num1, num2, bit;

  if (argc != 4) {
    fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
    exit(EXIT_FAILURE);
  }

  num1 = strtol(argv[1], NULL, 0);
  num2 = strtol(argv[2], NULL, 0);
  bit = strtol(argv[3], NULL, 0);

  compareBits(num1, num2, bit) ? printf("bits equal!\n")
                               : printf("bits not equal!\n");

  exit(EXIT_SUCCESS);
}

샘플 파일 형식:

./main 1234 1231 2

입력 파일 형식:

bits equal!

C에서 비트 비교를 위해 비트 OR(|) 연산자 사용하기

비트 OR 연산자(|)는 두 피연산자의 대응하는 비트들 사이의 비트 단위 비교를 수행합니다. 이 연산의 결과는 어느 한 피연산자에서 대응하는 비트 중 적어도 하나가 설정된 경우 각 비트가 설정되는 새 값이 됩니다.

비트 쌍에 적용하면 OR 연산은 다음 논리를 따릅니다:

`0 0`
`0 1`
`1 0`
`1 1`

비트 OR 연산을 설명하기 위해 다음 예를 살펴보세요:

#include <stdio.h>

int main() {
  unsigned int num1 = 9;  // Binary representation: 1001
  unsigned int num2 = 6;  // Binary representation: 0110

  unsigned int result = num1 | num2;

  printf("Result: %u\n", result);  // Output: 15 (Binary: 1111)

  return 0;
}

출력:

Result: 15

이 예제에서는 각각 값 9와 6으로 초기화된 두 개의 부호 없는 정수 num1과 num2가 있습니다. 이들의 이진수 표현은 1001과 0110입니다.

비트 OR 연산(num1 | num2)을 수행하면 결과는 이진수로 1111이며, 십진수로는 15입니다. 이는 num1 또는 num2 중 적어도 하나의 대응 비트가 설정되어 있음을 의미합니다.

C에서 비트 비교를 위해 비트 NOT(~) 연산자 사용하기

비트 NOT 연산자(~)는 단항 연산자로, 단일 피연산자에 대해 동작한다는 의미입니다. 이진수에 적용하면 각 비트가 반전되어 0은 1이 되고 1은 0이 됩니다.

예제 코드:

#include <stdio.h>

int main() {
  unsigned int num = 9;  // Binary representation: 1001

  unsigned int result = ~num;

  printf(
      "Result: %u\n",
      result);  // Output: 4294967286 (Binary: 11111111111111111111111111111010)

  return 0;
}

출력:

Result: 4294967286

이 예제에서는 부호 없는 정수 변수 num을 선언하고 값 9로 초기화합니다. 이진수로는 1001로 표현됩니다.

그런 다음 비트 NOT 연산자(~num)를 적용합니다. 이렇게 하면 모든 비트가 반전되어 이진수로 11111111111111111111111111111010이 됩니다.

결과가 콘솔에 출력되며, 십진수로는 4294967286입니다.

비트 비교를 위한 비트 NOT

비트 NOT 연산자의 응용 중 하나는 비트 비교입니다. 변수의 비트를 반전하면 특정 비트가 설정되었는지 여부를 쉽게 확인할 수 있습니다.

예제 코드:

#include <stdio.h>

int main() {
  unsigned int num = 9;  // Binary representation: 1001

  // Check if the 2nd bit is set
  unsigned int mask = 1 << 1;  // Shift 1 by 1 position to the left => 0002

  unsigned int result = ~num & mask;

  if (result == mask) {
    printf("2nd bit is set.\n");
  } else {
    printf("2nd bit is not set.\n");
  }

  return 0;
}

출력:

2nd bit is set.

이 예제에서는 변수 num의 두 번째 비트가 설정되었는지 확인하려고 합니다.

먼저 1을 왼쪽으로 1 위치 이동(1 << 1)하여 마스크를 만들면 이진수로 0002가 됩니다. 그런 다음 비트 NOT 연산자를 num에 적용하면 이진수로 11111111111111111111111111111010이 됩니다.

다음으로 반전된 num과 마스크 사이에 비트 AND 연산을 수행합니다. 이렇게 하면 두 번째 비트가 분리됩니다.

결과가 마스크와 같으면 두 번째 비트가 설정되었음을 의미하며 해당 메시지를 출력합니다. 그렇지 않으면 두 번째 비트가 설정되지 않았음을 나타내는 메시지를 출력합니다.

결론

C의 비트 연산자에 대한 이 포괄적인 탐구에서는 AND, OR, NOT와 같은 기본 연산을 다뤘습니다. 이러한 연산은 데이터 압축, 암호화, 임베디드 시스템 프로그래밍과 같은 저수준 데이터 조작을 수반하는 작업에 매우 유용합니다.

특히 개별 비트를 비교하기 위한 비트 NOT(~) 연산자의 사용을 자세히 살펴보았습니다. ~ 연산자를 적용하면 변수의 비트를 쉽게 반전하여 특정 비트가 설정되었는지 여부를 확인할 수 있습니다. 이 기법은 정밀한 비트 수준 조작이 필요한 시나리오에서 필수적입니다.

비트 연산을 이해하고 숙달하는 것은 하드웨어와의 직접적인 상호 작용을 수반하는 작업을 하거나 리소스가 제한된 환경을 위한 최적화된 솔루션이 필요한 프로그래머에게 매우 중요합니다. 이 기사에서 얻은 지식을 통해 이제 이러한 강력한 도구를 자신의 C 프로그래밍 프로젝트에 활용할 수 있게 되었습니다.