C++에서 비트 마스크 사용

Jinku Hu 2023년10월12일
  1. struct를 사용하여 C++에서 비트 마스크 정의 및 날짜 개체 구현
  2. structunion을 사용하여 비트 마스크를 정의하고 C++에서 날짜 객체 구현
  3. std::bitset을 사용하여 C++에서 비트 마스크 정의
C++에서 비트 마스크 사용

이 기사에서는 C++에서 비트 마스크를 사용하는 방법에 대한 여러 방법을 보여줍니다.

struct를 사용하여 C++에서 비트 마스크 정의 및 날짜 개체 구현

struct는 C++에서 널리 사용되는 데이터 구조입니다. 또한 C 언어와는 달리 class와는 약간 차이가 있습니다. 이 경우 여러 데이터 멤버로struct를 정의하기 만하면되지만 각 변수 이름과 지정된 정수 뒤에 사용되는 새로운 표기법:이 있습니다. 예제 코드에서 보듯이 우리는uint32_t 유형의 데이터 멤버로struct를 선언했고 오른쪽 숫자의 합은 32입니다.이 구조는struct가 단일uint32_t의 크기를 차지함을 의미합니다. 데이터 유형을 메모리에 저장하고 사용자는 비트 필드 범위 (23 : 5 : 4)에 개별적으로 액세스 할 수 있습니다.

이 방법은 주로 유사한 ‘구조체’로 압축 될 수있는 데이터 구조의 메모리 사용을 절약하는 데 사용됩니다. 또한 C++ 프로그래밍 언어에서 1 바이트보다 작은 데이터에 액세스하는 일반적인 방법 중 하나입니다. 첫 번째 멤버 year는 최대 223-1까지의 정수 값만 포함 할 수 있으며 다른 멤버도 비슷하게 따릅니다.

#include <iostream>

using std::cout;
using std::endl;

struct {
  uint32_t year : 23;
  uint32_t day : 5;
  uint32_t month : 4;
} typedef Bitfield;

int main() {
  Bitfield date = {2020, 13, 12};

  cout << "sizeof Bitfield: " << sizeof(date) << " bytes\n";
  cout << "date: " << date.day << "/" << date.month << "/" << date.year << endl;

  return EXIT_SUCCESS;
}

출력:

sizeof Bitfield: 4 bytes
date: 13/12/2020

structunion을 사용하여 비트 마스크를 정의하고 C++에서 날짜 객체 구현

이전 방법은 비트 마스크를 구현하는 충분하고 올바른 방법입니다. 그러나 한 가지 단점이 있습니다. 멤버에 값을 액세스하고 할당하는 데는 기본 제공 형식에 대한 작업보다 상대적으로 더 많은 시간이 걸립니다. 이는struct와 단일 내장 유형 변수로 구성된union 유형 객체를 구현하여 해결할 수 있습니다. struct는 레이아웃이 이전 방법에서 생성 한 것과 동일합니다. 이 경우 차이점은struct와 동일한 크기를 차지하는 변수uint32_t ydm입니다.

아이디어는 데이터 멤버의 값을 훨씬 빠르게 초기화 / 할당하는 것입니다. 즉, 비트가struct에 저장 될 때 비트 레이아웃과 정확히 일치하는 비트 연산으로 정수를 생성 한 다음 단일uint32_t 멤버에 할당합니다. 이렇게하면 세 멤버 각각에 대해 동일한 작업을 반복하는 대신 데이터에 한 번 액세스하는 시간이 절약됩니다.

비트 연산은 비교적 간단합니다. 즉, struct에서 첫 번째 멤버의 값으로 시작하는데, 이는 이전 멤버가 차지하는 비트 수만큼 왼쪽으로 이동 한 다음 멤버의 결과와 OR-ed이며 유사하게 따릅니다.

#include <iostream>

using std::cout;
using std::endl;

union BitfieldFast {
  struct {
    uint32_t year : 23;
    uint32_t day : 5;
    uint32_t month : 4;
  };
  uint32_t ydm;
};

int main() {
  BitfieldFast date_f{};
  date_f.ydm = 2020 | (13 << 23) | (12 << 28);

  cout << "sizeof BitfieldFast: " << sizeof(date_f) << " bytes\n";
  cout << "date: " << date_f.day << "/" << date_f.month << "/" << date_f.year
       << endl;

  return EXIT_SUCCESS;
}
sizeof BitfieldFast: 4 bytes
date: 13/12/2020

std::bitset을 사용하여 C++에서 비트 마스크 정의

std::bitset은 바이너리 마스크 데이터를 저장하기위한 클래스를 포함하는 표준 라이브러리 기능입니다. bitset에는 여러 가지 유용한 조작 함수가 내장되어 있으며 선언이 매우 쉽습니다. 이진 문자열값 또는 여러 숫자 값으로 초기화 할 수 있습니다. 비트 연산은 기본 제공 메서드이며 오버로드 된 기존 연산자로 호출 할 수 있습니다. reset 메서드는 호출 된bitset을 영구적으로 수정합니다.

#include <bitset>
#include <iostream>

using std::cout;
using std::endl;

int main() {
  std::bitset<16> bs1("1100100011110010");
  std::bitset<16> bs2(0xfff0);
  cout << "bs1        : " << bs1 << endl;
  cout << "bs2        : " << bs2 << endl;
  cout << "NOT bs1    : " << ~bs1 << endl;
  cout << "bs1 AND bs2: " << (bs1 & bs2) << endl;
  cout << "bs1 reset  : " << bs1.reset() << endl;

  return EXIT_SUCCESS;
}

출력:

bs1        : 1100100011110010
bs2        : 1111111111110000
NOT bs1    : 0011011100001101
bs1 AND bs2: 1100100011110000
bs1 reset  : 0000000000000000
작가: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook