programing

C/C++ 비트가 1개 설정되어 있는지 확인합니다(예: int 변수).

javaba 2022. 9. 30. 10:43
반응형

C/C++ 비트가 1개 설정되어 있는지 확인합니다(예: int 변수).

int temp = 0x5E; // in binary 0b1011110.

비트 이동 및 마스킹 없이 온도에서 비트 3이 1인지 0인지 확인할 수 있는 방법이 있습니까?

이 기능을 내장하고 있는지, 아니면 제가 직접 작성해야 하는지 알고 싶을 뿐입니다.

C에서 비트 조작을 숨기려면 다음과 같이 매크로를 쓸 수 있습니다.

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

오른쪽 끝의th n비트를 확인하려면 다음과 같이 사용합니다.

CHECK_BIT(temp, n - 1)

C++ 에서는, std:: bitset 를 사용할 수 있습니다.

비트 N(0부터 시작)이 설정되어 있는지 확인합니다.

temp & (1 << N)

여기에는 내장 함수가 없습니다.

선택된 답변이 하고 있는 것은 실제로는 잘못된 것입니다.아래 함수는 비트가 실제로 활성화되었는지 여부에 따라 비트 위치 또는 0을 반환합니다.이것은 포스터가 요구한 것이 아니다.

#define CHECK_BIT(var,pos) ((var) & (1<<(pos)))

이것이 그 포스터가 원래 찾던 것이다.아래 함수는 비트가 활성화되고 위치가 아닌 경우 1 또는 0을 반환합니다.

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)

C++이면 std::bitset을 사용합니다.간단하죠.단도직입적으로.바보 같은 실수 따윈 할 수 없어

typedef std::bitset<sizeof(int)> IntBits;
bool is_set = IntBits(value).test(position);

아니면 이 바보 같은 짓은 어때?

template<unsigned int Exp>
struct pow_2 {
    static const unsigned int value = 2 * pow_2<Exp-1>::value;
};

template<>
struct pow_2<0> {
    static const unsigned int value = 1;
};

template<unsigned int Pos>
bool is_bit_set(unsigned int value)
{
    return (value & pow_2<Pos>::value) != 0;
} 

bool result = is_bit_set<2>(value);
#define CHECK_BIT(var,pos) ((var>>pos) & 1)

pos - 0부터 시작하는 비트 위치.

0 또는 1을 반환합니다.

그래, 내가 이런 식으로 할 "필요"가 없다는 걸 알아요.하지만 저는 보통 이렇게 씁니다.

    /* Return type (8/16/32/64 int size) is specified by argument size. */
template<class TYPE> inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }

template<class TYPE> inline bool IsBitSet(const TYPE & x, const TYPE & y)
{ return 0 != (x & y); }

예:

IsBitSet( foo, BIT(3) | BIT(6) );  // Checks if Bit 3 OR 6 is set.

무엇보다도 이 접근방식은 다음과 같습니다.

  • 8/16/32/64비트 정수를 수용할 수 있습니다.
  • 본인의 인식과 동의 없이 IsBitSet(int32,int64) 콜을 검출합니다.
  • 인라인 템플릿이므로 오버헤드를 호출하는 함수는 없습니다.
  • const & references이므로 복제/삭제할 필요가 없습니다.그리고 컴파일러는 인수를 변경하려는 오타를 모두 검출할 것을 보증합니다.
  • 0!=을 사용하면 코드가 더욱 명확해지고 명확해집니다.코드 작성의 주된 포인트는, 스킬이 낮은 프로그래머를 포함한 다른 프로그래머와 항상 명확하고 효율적으로 통신하는 것입니다.
  • ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★일반적으로 템플리트 함수는 인수를 여러 번 평가하는 문제를 회피합니다.##은 #은(는) #는)입니다.
    #ABS)< : ( : : # 의 : # 의 abs ABS(X)((X)<0) ? - (X) : (X) : (X)
    ABS(i++);

선행 응답에서는 비트체크를 처리하는 방법을 보여 줍니다만, 실제로는 정수로 인코딩된 플래그에 관한 것이 대부분입니다.이것은 선행 사례에서는 명확하게 정의되어 있지 않습니다.

일반적인 시나리오에서는 플래그가 참조하는 특정 비트에 대해 비트가 1인 정수로 정의됩니다.다음 예에서는 플래그 리스트의 ANY 플래그가 정수에 포함되어 있는지(복수의 에러 플래그가 연결되어 있는지) 또는 EVERY 플래그가 정수에 포함되어 있는지(복수의 성공 플래그가 연결되어 있는지) 확인할 수 있습니다.

정수로 플래그를 처리하는 방법의 예를 다음에 나타냅니다.

라이브의 예는, https://rextester.com/XIKE82408 에서 입수할 수 있습니다.

//g++  7.4.0

#include <iostream>
#include <stdint.h>

inline bool any_flag_present(unsigned int value, unsigned int flags) {
    return bool(value & flags);
}

inline bool all_flags_present(unsigned int value, unsigned int flags) {
    return (value & flags) == flags;
}

enum: unsigned int {
    ERROR_1 = 1U,
    ERROR_2 = 2U, // or 0b10
    ERROR_3 = 4U, // or 0b100
    SUCCESS_1 = 8U,
    SUCCESS_2 = 16U,
    OTHER_FLAG = 32U,
};

int main(void)
{
    unsigned int value = 0b101011; // ERROR_1, ERROR_2, SUCCESS_1, OTHER_FLAG
    unsigned int all_error_flags = ERROR_1 | ERROR_2 | ERROR_3;
    unsigned int all_success_flags = SUCCESS_1 | SUCCESS_2;
    
    std::cout << "Was there at least one error: " << any_flag_present(value, all_error_flags) << std::endl;
    std::cout << "Are all success flags enabled: " << all_flags_present(value, all_success_flags) << std::endl;
    std::cout << "Is the other flag enabled with eror 1: " << all_flags_present(value, ERROR_1 | OTHER_FLAG) << std::endl;
    return 0;
}

이 모든 비트의 이동 조작과 라이브러리 기능의 필요성은 무엇입니까?OP가 게시된 값 1011110이 있고 오른쪽에서 세 번째 위치에 있는 비트가 설정되어 있는지 알고 싶다면 다음을 수행하십시오.

int temp = 0b1011110;
if( temp & 4 )   /* or (temp & 0b0100) if that's how you roll */
  DoSomething();

또는 #include 없이 코드의 미래 독자들이 더 쉽게 해석할 수 있는 내용:

int temp = 0b1011110;
_Bool bThirdBitIsSet = (temp & 4) ? 1 : 0;
if( bThirdBitIsSet )
  DoSomething();

조금 더 예뻐 보이고 싶은 경우:

#include <stdbool.h>
int temp = 0b1011110;
bool bThirdBitIsSet = (temp & 4) ? true : false;
if( bThirdBitIsSet )
  DoSomething();

비트셋(http://www.cppreference.com/wiki/stl/bitset/start)을 사용할 수 있습니다.

한 가지 방법은 다음 조건 내에서 확인하는 것입니다.

if ( (mask >> bit ) & 1)

설명 프로그램은 다음과 같습니다.

#include <stdio.h>

unsigned int bitCheck(unsigned int mask, int pin);

int main(void){
   unsigned int mask = 6;  // 6 = 0110
   int pin0 = 0;
   int pin1 = 1;
   int pin2 = 2;
   int pin3 = 3;
   unsigned int bit0= bitCheck( mask, pin0);
   unsigned int bit1= bitCheck( mask, pin1);
   unsigned int bit2= bitCheck( mask, pin2);
   unsigned int bit3= bitCheck( mask, pin3);

   printf("Mask = %d ==>>  0110\n", mask);

   if ( bit0 == 1 ){
      printf("Pin %d is Set\n", pin0);
   }else{
      printf("Pin %d is not Set\n", pin0);
   }

    if ( bit1 == 1 ){
      printf("Pin %d is Set\n", pin1);
   }else{
      printf("Pin %d is not Set\n", pin1);
   }

   if ( bit2 == 1 ){
      printf("Pin %d is Set\n", pin2);
   }else{
      printf("Pin %d is not Set\n", pin2);
   }

   if ( bit3 == 1 ){
      printf("Pin %d is Set\n", pin3);
   }else{
      printf("Pin %d is not Set\n", pin3);
   }
}

unsigned int bitCheck(unsigned int mask, int bit){
   if ( (mask >> bit ) & 1){
      return 1;
   }else{
      return 0;
   }
}

출력:

Mask = 6 ==>>  0110
Pin 0 is not Set
Pin 1 is Set
Pin 2 is Set
Pin 3 is not Set

std:: bitset 사용

#include <bitset>
#include <iostream>

int main()
{
    int temp = 0x5E;
    std::bitset<sizeof(int)*CHAR_BITS>   bits(temp);

    // 0 -> bit 1
    // 2 -> bit 3
    std::cout << bits[2] << std::endl;
}

PDF에서 개체의 플래그를 정의하는 32비트 정수를 읽으려고 했는데 이 정수가 작동하지 않았습니다.

어떤 수정이 정의를 변경했는지:

#define CHECK_BIT(var,pos) ((var & (1 << pos)) == (1 << pos))

피연산자는 둘 다 1에 있는 플래그가 있는 정수를 반환하고 부울에 올바르게 캐스팅되지 않았습니다.이것이 트릭을 실행했습니다.

나는 이것을 사용한다.

#define CHECK_BIT(var,pos) ( (((var) & (pos)) > 0 ) ? (1) : (0) )

여기서 "pos"는 2^n으로 정의된다(예: 1,2,4,8,16,32 ...).

반환: true인 경우 1(false인 경우 0)

빠르고 최적의 매크로

#define get_bit_status()    ( YOUR_VAR  &   ( 1 << BITX ) )

.
.

if (get_rx_pin_status() == ( 1 << BITX ))
{
    do();
}

왜 이렇게 간단한 걸 쓰지 않는 거죠?

uint8_t status = 255;
cout << "binary: ";

for (int i=((sizeof(status)*8)-1); i>-1; i--)
{
  if ((status & (1 << i)))
  {
    cout << "1";
  } 
  else
  {
    cout << "0";
  }
}

바이너리: 력 : 이 : 이 :11111111

이 비트 필드의 설명에 따라 필드를 직접 정의하고 액세스하는 방법이 있습니다.이 엔트리의 예는 다음과 같습니다.

struct preferences {
    unsigned int likes_ice_cream : 1;
    unsigned int plays_golf : 1;
    unsigned int watches_tv : 1;
    unsigned int reads_books : 1;
}; 

struct preferences fred;

fred.likes_ice_cream = 1;
fred.plays_golf = 1;
fred.watches_tv = 1;
fred.reads_books = 0;

if (fred.likes_ice_cream == 1)
    /* ... */

또한 다음과 같은 경고가 있습니다.

그러나 구조체의 비트 멤버에는 실질적인 단점이 있습니다.첫째, 메모리 내의 비트 순서는 아키텍처에 따라 다르며 메모리 패딩 규칙은 컴파일러마다 다릅니다.게다가 많은 인기 있는 컴파일러는 비트멤버 읽기 및 쓰기에 비효율적인 코드를 생성하고 있으며, 대부분의 머신이 메모리 내의 임의의 비트세트를 조작할 수 없고 대신 워드 전체를 로드 및 저장해야 하기 때문에 비트필드(특히 멀티프로세서 시스템)와 관련된 심각한 스레드 안전 문제가 발생할 수 있습니다.

나는 이것을 만든다:

LATG비트LATG0=((m&0x8)>0; //m의 비트-2가 1인지 확인하려면

가장 빠른 방법은 마스크 룩업 테이블인 것 같습니다.

이동 및 마스킹을 "시뮬레이션"할 수 있습니다. if ( ( ( 0 x 5e / ( 2 * 2 * 2 ) % 2 ) ...

즉, _bittest 본질적인 명령이 있습니다.

낮은 수준의 x86 전용 솔루션의 경우 x86 TEST opcode를 사용합니다.

컴파일러는 _bittest를 이 상태로 변환합니다.

하드코드 방식을 원한다면:

 #define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )

이 하드웨어에 의존하여 비트오더 7654 3210 및 var가 8비트임을 전제로 합니다.

#include "stdafx.h"
#define IS_BIT3_SET(var) ( ((var) & 0x04) == 0x04 )
int _tmain(int argc, _TCHAR* argv[])
{
    int temp =0x5E;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x00;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0x04;
    printf(" %d \n", IS_BIT3_SET(temp));
    temp = 0xfb;
    printf(" %d \n", IS_BIT3_SET(temp));
    scanf("waitng %d",&temp);

    return 0;
}

결과:

1 0 1 0

지금은 답변이 늦었지만 단순히 POWER와 MODELULS 연산자를 사용하여 N번째 비트가 설정되었는지 여부를 확인할 수 있는 간단한 방법이 있습니다.

'temp'에 N번째 비트가 설정되어 있는지 알고 싶다고 합시다.다음 부울식은 비트가 설정되어 있으면 true, 설정되어 있지 않으면 0이 됩니다.

  • (온도 모듈러스 2^N+1 >= 2^N )

다음 예를 생각해 보겠습니다.

  • int temp = 0x5E; // 이진수 0b101110 // 비트 0은 LSB입니다.

세 번째 비트가 설정되어 있는지 알고 싶으면

  • (94 모듈러스 16) = 14 > 2^3

따라서 식에서는 true를 반환하고 세 번째 비트가 설정되었음을 나타냅니다.

언급URL : https://stackoverflow.com/questions/523724/c-c-check-if-one-bit-is-set-in-i-e-int-variable

반응형