2014-10-24 2 views
-5

특정 비트 범위가 켜져 있는지 또는 꺼져 있는지를 확인하기 위해 매크로를 작성하려고합니다. 사용자는 숫자, 시작 비트 및 종료 비트를 입력한다고 가정합니다. 따라서 사용자가 10 진수 31, 2, 4를 입력하면 2에서 4까지의 모든 비트가 1인지 확인해야합니다. 모두 1이면 모두 true를 반환합니다. 모두 1이 아니면 false를 반환합니다. 이 경우 모두 1이므로 true를 반환합니다.비트 연산?

#define ALLON(X, S, E) //(MACRO HERE) 

어떻게해야합니까? 이 같은

+1

가능한 복제본 [C/C++에서 어떻게 단일 비트를 설정하고 해제하고 토글합니까?] (http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle -a-single-bit-in-cc) – 2501

+1

@DoxyLover : 범위에 걸쳐 반복 할 필요가 없습니다. –

+1

@ 2501 -이 내용이 중복 된 것에 대해서는 동의하지 않습니다. 연결된 질문에서 단일 비트에 대해 이야기합니다. OP는 시작 비트와 종료 비트 수에 의해 지정된 일련의 비트를 원합니다. – DoxyLover

답변

0

뭔가 : 여기

#define GET_MASK(S, E)  (((1UL << (E - S + 1)) - 1) << S) 

#define ALLOCN(X, S, E)  (((GET_MASK(S,E) & X) == GET_MASK(S,E)) ? 1 : 0) 

, GET_MASK 당신이 확인하고자하는 비트에 해당하는 마스크를 제공합니다. ALLOCN은 정확히 모든 비트가 X 이외의 값으로 설정된 경우 1을 반환합니다. (비트 번호가 0에서 시작한다고 가정 함)

중요 : 여기서 오버플로가 있는지 확인하지 않습니다.

희망이 도움이됩니다.

+0

마스크와 비트 'AND'를 쓰면, * all *이 설정되었을 때뿐만 아니라 비트의 * any *가 설정되면 참이됩니다. 세트. 또한,이 알고리즘은 제대로 작동하지 않습니다. 몇 가지 숫자로 시도해 보면 알 수 있습니다. –

+0

좋은 캐치 폴! 당신 말이 맞아요. 마스크 & X가 정확하게 마스크를 제공하는지 확인해야합니다! 그에 따라 답변을 업데이트했습니다. – Furquan

1

일부 기본 비트 이동 및 비트 논리 연산을 통해이를 수행 할 수 있습니다. 이 그것을 할 수 있습니다 :

#include <stdio.h> 

#define ALLON(X,S,E) ((X & (~((~0U << E) | ~(~0U << (S - 1))))) == (~((~0U << E) | ~(~0U << (S - 1))))) 

/* 
    Or, simplifying with two macros... 

    #define ALLMASK(S,E) (~((~0U << E) | ~(~0U << (S - 1)))) 
    #define ALLON(X,S,E) ((X & ALLMASK(S,E)) == ALLMASK(S,E)) 
*/ 

char * convert_to_8bit(char * buffer, const unsigned int n) 
{ 
    size_t k = 0; 
    for (unsigned int i = 128; i > 0; i >>= 1) { 
     if (n & i) { 
      buffer[k++] = '1'; 
     } 
     else { 
      buffer[k++] = '0'; 
     } 
    } 
    return buffer; 
} 

int main(void) 
{ 
    char buffer[9] = {0}; 

    printf("1 in binary is %s\n", convert_to_8bit(buffer, 1)); 
    printf("ALLON(1, 2, 4) is %s\n", ALLON(1, 2, 4) ? "true" : "false"); 
    printf("ALLON(1, 1, 1) is %s\n", ALLON(1, 1, 1) ? "true" : "false"); 

    printf("30 in binary is %s\n", convert_to_8bit(buffer, 30)); 
    printf("ALLON(30, 2, 4) is %s\n", ALLON(30, 2, 4) ? "true" : "false"); 
    printf("ALLON(30, 1, 1) is %s\n", ALLON(30, 1, 1) ? "true" : "false"); 
    printf("ALLON(30, 5, 5) is %s\n", ALLON(30, 5, 5) ? "true" : "false"); 
    printf("ALLON(30, 5, 6) is %s\n", ALLON(30, 5, 6) ? "true" : "false"); 

    return 0; 
} 

출력 :

[email protected]:~/src/sandbox$ ./bs 
1 in binary is 00000001 
ALLON(1, 2, 4) is false 
ALLON(1, 1, 1) is true 
30 in binary is 00011110 
ALLON(30, 2, 4) is true 
ALLON(30, 1, 1) is false 
ALLON(30, 5, 5) is true 
ALLON(30, 5, 6) is false 
[email protected]:~/src/sandbox$ 

간단히, 우리가 ALLON하고있는 가정 (31, 2, 4) :

  1. ~0U << E11111111 왼쪽으로 이동을합니다 그것 4, 그래서 당신은 얻는다 11110000
  2. ~0U << (S - 1)11111111를 잡는다. 그리고 left는 그것을 1로 바꾼다. 그래서 당신은를 얻는다.
  3. ~(~0U << (S - 1)) 당신이 바로이 당신에게 비트 2, 3, 4는 당신에게 비트는 관심있는 00001110를 제공합니다 0
  4. 부정이다 11110001를 제공 논리합 연산 당신에게 00000001
  5. 을 제공 한 일을 부정
  6. X을 ANDing하는 것이 마스크 자체와 같으면 모든 비트가 설정됩니다.

아마도 더 짧은 방법 일 수 있지만이 방법은 이해하기 쉽습니다.