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

2009年02月07日に質問されました。  ·  閲覧回数 277.8k回  ·  ソース

Milan picture
2009年02月07日
int temp = 0x5E; // in binary 0b1011110.

ビットシフトやマスキングを行わずに、温度のビット3が1か0かを確認する方法はありますか?

このための組み込み関数があるかどうか、または自分で作成する必要があるかどうかを知りたいだけです。

回答

mouviciel picture
2009年02月07日
162

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

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

このように使用して、右端からn番目のビットをチェックします。

CHECK_BIT(temp, n - 1)

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

Joao da Silva picture
2009年02月07日
87

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

temp & (1 << N)

このための組み込み関数はありません。

user21714 picture
2009年02月08日
29

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);
shocker92 picture
2015年08月07日
15

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

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

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

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
Mr.Ree picture
2009年02月08日
14

ええ、私はそれをこのようにする必要ないことを知っています。 しかし、私は通常次のように書いています。

    /* 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&参照なので、複製/コピーする必要はありません。 また、コンパイラが引数を変更しようとするタイプミスを検出することが保証されています。
  • 0!=は、コードをより明確でわかりやすくします。 コードを書く上での主なポイントは、スキルの低いプログラマーを含め、他のプログラマーと常に明確かつ効率的にコミュニケーションをとることです。
  • この特定のケースには適用できませんが...一般に、テンプレート化された関数は、引数を複数回評価する問題を回避します。 一部の#defineマクロに関する既知の問題。
    例:#define ABS(X)(((X)<0)?-(X):( X))
    ABS(i ++);
gimel picture
2009年02月07日
10

このビットフィールドの説明によると

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

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

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

yawmark picture
2009年02月07日
6

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

Martin York picture
2009年02月08日
6

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;
}
Dave Van den Eynde picture
2009年02月07日
4

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

AnthropicDream picture
2018年04月09日
4

私はこれを使用します:

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

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

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