web-dev-qa-db-ja.com

C / C ++で1ビットが設定されているかどうか、つまりint変数をチェックします

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

Tempのビット3が1か0かをビットシフトとマスキングなしでチェックする方法はありますか。

この機能が組み込まれているかどうかを知りたい、または自分で作成することを余儀なくされています。

97
Milan

Cでは、ビット操作を非表示にする場合は、マクロを記述できます。

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

この方法でnを確認します番目 右端から少し:

CHECK_BIT(temp, n - 1)

C++では、 std :: bitset を使用できます。

150
mouviciel

ビットN(0から始まる)が設定されているかどうかを確認します。

temp & (1 << N)

これには組み込み関数はありません。

82
Joao da Silva

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);
24
user21714

選択した答えが実際に間違っていること。以下の関数は、ビットが実際に有効になっているかどうかに応じて、ビット位置または0を返します。これは、ポスターが求めていたものではありません。

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

これは、ポスターが元々探していたものです。以下の関数は、位置ではなくビットが有効になっている場合、1または0を返します。

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

ええ、私は "have"しないことを知っています。しかし、私は通常書く:

    /* 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&参照なので、何もありませんneeds複製/コピーする必要があります。そして、引数を変更しようとするタイプミスをコンパイラーが拾うことを保証します。
  • !=は、コードをより明確かつ明確にします。コードを書く主な目的は、常に、スキルの低いプログラマを含む他のプログラマと明確かつ効率的に通信することです。
  • この特定のケースには適用されませんが...一般に、テンプレート関数は引数を複数回評価する問題を回避します。いくつかの#defineマクロの既知の問題。
    E.g .: #define ABS(X)(((X)<0)?-(X):(X))
    ABS(i ++);
11
Mr.Ree

ビットフィールドのこの説明 によると、フィールドを直接定義してアクセスする方法があります。このエントリの例は次のとおりです。

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)
    /* ... */

また、そこには警告があります:

ただし、構造体のビットメンバーには実用上の欠点があります。まず、メモリ内のビットの順序はアーキテクチャに依存し、メモリパディングルールはコンパイラごとに異なります。さらに、多くの一般的なコンパイラは、ビットメンバーの読み取りおよび書き込み用に非効率的なコードを生成します。また、ほとんどのマシンはメモリ内の任意のビットセットを操作できないため、ビットフィールド(特にマルチプロセッサシステム)に関連する深刻なスレッドセーフの問題が発生する可能性があります。しかし、代わりに単語全体をロードして保存する必要があります。

11
gimel

ビットセットを使用できます- http://www.cppreference.com/wiki/stl/bitset/start

6
yawmark

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;
}
5
Martin York

私はこれを使用します:

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

ここで、「pos」は2 ^ nとして定義されます(例:1,2,4,8,16,32 ...)

戻り値:trueの場合は1、falseの場合は0

4
AnthropicDream

つまり、 _ bittest 組み込み命令があります。

4

pDFのオブジェクトのフラグを定義する32ビット整数を読み取ろうとしていましたが、これはうまくいきませんでした

何が修正されたのは、定義を変更していた:

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

オペランド&は、両方が1にあるフラグを含む整数を返しますが、ブール値に適切にキャストされていませんでした。

3
Ismael

シフトとマスキングを「シミュレート」できます:if((0x5e /(2 * 2 * 2))%2)...

2
Leonidas

低レベルのx86固有のソリューションの場合は、x86 TEST opcodeを使用します。

コンパイラは _ bittest をこれに変換する必要があります...

2
jheriko

こんなシンプルなものを使ってみませんか?

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

1
zeilja

実際にハードコードされた方法が必要な場合:

 #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

0
simon

1つのアプローチは、次の条件内でチェックすることです。

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
0
Michi

今すぐ答えるのはかなり遅いですが、単純にPOWERおよびMODULUS数学演算子を使用して、N番目のビットが設定されているかどうかを調べる簡単な方法があります。

'temp'にN番目のビットが設定されているかどうかを知りたいとしましょう。次のブール式は、ビットが設定されている場合はtrue、それ以外の場合は0を返します。

  • (temp MODULUS 2 ^ N + 1> = 2 ^ N)

次の例を考えてみましょう。

  • int temp = 0x5E; //バイナリ0b1011110で//ビット0はLSB

3番目のビットが設定されているかどうかを知りたい場合は、

  • (94 MODULUS 16)= 14> 2 ^ 3

したがって、式はtrueを返し、3番目のビットが設定されていることを示します。

0
Ouroboros