문제

나는 내가 가지고 있는 데이터 압축 아이디어를 구현하려고 노력하고 있으며 대규모 테스트 데이터 모음에 대해 이를 실행하는 것을 상상하고 있기 때문에 C로 코딩하려고 생각했습니다. Tcl.)

C에 관한 O'Reilly 'cow' 책을 살펴보면서 비트 비교 및 ​​연산자를 수행하고 싶기 때문에 간단한 'char' 또는 'int' 유형 변수의 비트를 단순히 색인화할 수는 없다는 것을 깨달았습니다.

이 인식이 맞습니까?비트를 표현하기 위해 열거된 유형을 사용하는 것이 합리적입니까(그리고 이들의 배열을 만들고 char로/에서 변환하는 함수 작성)?그렇다면 그러한 유형과 함수가 이미 표준 라이브러리 어딘가에 정의되어 있습니까?다른 (더 나은?) 접근법이 있습니까?누군가가 나에게 알려줄 수 있는 예제 코드가 있나요?

감사해요 -

도움이 되었습니까?

해결책

Kyle이 말한 내용에 이어 매크로를 사용하여 어려운 작업을 수행할 수 있습니다.

것이 가능하다.

n번째 비트를 설정하려면 OR을 사용합니다.

x |= (1 << 5);// 오른쪽으로 6 번째로 설정됩니다

비트를 지우려면 AND를 사용하세요.

x &= ~(1 << 5);// 오른쪽으로 6 번째로 지워집니다

비트를 뒤집으려면 XOR을 사용하십시오.

x ^= (1 << 5);// 오른쪽에서 6번째 뒤집기

또는...

#define GetBit(var, bit) ((var & (1 << bit)) != 0) // Returns true / false if bit is set
#define SetBit(var, bit) (var |= (1 << bit))
#define FlipBit(var, bit) (var ^= (1 << bit))

그런 다음 다음과 같은 코드에서 사용할 수 있습니다.

int myVar = 0;
SetBit(myVar, 5);
if (GetBit(myVar, 5))
{
  // Do something
}

다른 팁

것이 가능하다.

n번째 비트를 설정하려면 OR을 사용합니다.

x |= (1 << 5); // sets the 5th-from right

비트를 지우려면 AND를 사용하세요.

x &= ~(1 << 5); // clears 5th-from-right

비트를 뒤집으려면 XOR을 사용하십시오.

x ^= (1 << 5); // flips 5th-from-right

비트 값을 얻으려면 Shift와 AND를 사용하세요.

(x & (1 << 5)) >> 5 // gets the value (0 or 1) of the 5th-from-right

메모:오른쪽으로 시프트 5는 값이 0 또는 1인지 확인하는 것입니다.0/0이 아닌 0에만 관심이 있다면 교대 근무 없이 지나갈 수 있습니다.

에 대한 답변을 살펴보세요 이 질문.

이론

내장 데이터 유형의 n번째 비트에 액세스하거나 설정하기 위한 C 구문은 없습니다(예:'문자').그러나 논리 AND 연산을 사용하여 비트에 액세스하고 논리 OR 연산을 사용하여 비트를 설정할 수 있습니다.

예를 들어, 1101을 보유하는 변수가 있고 왼쪽에서 두 번째 비트를 확인하고 싶다고 가정해 보겠습니다.0100으로 논리 AND를 수행하면 됩니다.

1101
0100
---- AND
0100

결과가 0이 아니면 두 번째 비트가 설정되어 있어야 합니다.그렇지 않으면 설정되지 않았습니다.

왼쪽에서 세 번째 비트를 설정하려면 0010을 사용하여 논리적 OR을 수행합니다.

1101
0010
---- OR
1111

C 연산자 && (for and) 및 ||를 사용할 수 있습니다. (또는) 이러한 작업을 수행하기 위해.비트 액세스 패턴(위 예에서는 0100 및 0010)을 직접 구성해야 합니다.비결은 최하위 비트(LSB)가 1을 계산하고 다음 LSB가 2를 계산한 다음 4를 계산한다는 점을 기억하는 것입니다.따라서 n번째 LSB(0에서 시작)에 대한 비트 액세스 패턴은 단순히 2^n 값입니다.C에서 이를 계산하는 가장 쉬운 방법은 이진 값 0001(이 4비트 예에서)을 필요한 자릿수만큼 왼쪽으로 이동하는 것입니다.이 값은 부호 없는 정수와 같은 수량에서 항상 1과 같으므로 이는 단지 '1 << n'입니다.

unsigned char myVal = 0x65; /* in hex; this is 01100101 in binary. */

/* Q: is the 3-rd least significant bit set (again, the LSB is the 0th bit)? */
unsigned char pattern = 1;
pattern <<= 3; /* Shift pattern left by three places.*/

if(myVal && (char)(1<<3)) {printf("Yes!\n");} /* Perform the test. */

/* Set the most significant bit. */
myVal |= (char)(1<<7);

이 예제는 테스트되지 않았지만 일반적인 아이디어를 설명하는 데 도움이 됩니다.

특정 인덱스를 사용하여 비트 상태를 쿼리하려면 다음을 수행하세요.

int index_state = variable & ( 1 << bit_index );

비트를 설정하려면:

varabile |= 1 << bit_index;

비트를 다시 시작하려면:

variable &= ~( 1 << bit_index );

개별 비트는 다음과 같이 인덱싱될 수 있습니다.

다음과 같은 구조체를 정의합니다.

struct
{
  unsigned bit0     : 1;
  unsigned bit1     : 1;
  unsigned bit2     : 1;
  unsigned bit3     : 1;
  unsigned reserved : 28;
} bitPattern;   

이제 "value"라는 var의 개별 비트 값을 알고 싶다면 다음을 수행하십시오.

CopyMemory( &input, &value, sizeof(value) );

비트 2가 높은지 낮은지 확인하려면 다음을 수행하세요.

int state = bitPattern.bit2;

도움이 되었기를 바랍니다.

비트필드를 사용해 보세요.구현은 컴파일러에 따라 다를 수 있으므로 주의하세요.

http://publications.gbdirect.co.uk/c_book/chapter6/bitfields.html

약간의 색인을 생성하려면 다음을 수행할 수 있습니다.

bit = (char & 0xF0) >> 7;

문자의 msb를 얻습니다.오른쪽 시프트를 생략하고 0에서 테스트를 수행할 수도 있습니다.

bit = char & 0xF0;

비트가 설정되면 결과는 > 0이 됩니다.

분명히 다른 비트를 얻으려면 마스크를 변경해야 합니다(주의:명확하지 않은 경우 0xF는 비트 마스크입니다.수많은 마스크를 정의하는 것이 가능합니다.

#define BIT_0 0x1 // or 1 << 0
#define BIT_1 0x2 // or 1 << 1
#define BIT_2 0x4 // or 1 << 2
#define BIT_3 0x8 // or 1 << 3

등...

이는 다음을 제공합니다.

bit = char & BIT_1;

위 코드에서 이러한 정의를 사용하여 매크로나 함수 내에서 비트를 성공적으로 인덱싱할 수 있습니다.

비트를 설정하려면:

char |= BIT_2;

조금 지우려면:

char &= ~BIT_3

조금 전환하려면

char ^= BIT_4

이 도움?

비트에 대한 표준 라이브러리 컨테이너가 있습니다.표준::벡터.공간 효율성을 높이기 위해 도서관에 특화되어 있습니다.Boost Dynamic_bitset 클래스도 있습니다.

이를 통해 기본 저장소의 값당 1비트를 사용하여 일련의 부울 값에 대한 작업을 수행할 수 있습니다.

동적 비트세트 문서화 강화

STL 문서는 컴파일러 문서를 참조하세요.

물론 다른 정수 유형의 개별 비트를 직접 처리할 수도 있습니다.그렇게 하려면 높은 비트가 설정된 값에서 오른쪽 시프트를 수행하기로 결정한 경우 정의되지 않은 동작이 발생하지 않도록 부호 없는 유형을 사용해야 합니다.그러나 컨테이너를 원하는 것 같습니다.

이것이 필요한 것보다 32배 더 많은 공간을 차지한다고 주장한 논평자에게:Boost::dynamic_bitset 및 벡터는 항목당 1비트를 사용하도록 특화되어 있으므로 실제로 기본 유형의 비트 수보다 더 많은 것을 원한다고 가정하면 공간 패널티가 없습니다.이러한 클래스를 사용하면 효율적인 기본 스토리지를 통해 대형 컨테이너의 개별 비트를 처리할 수 있습니다.32비트만 원한다면 반드시 int를 사용하세요.많은 수의 비트를 원할 경우 라이브러리 컨테이너를 사용할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top