C / C ++检查是否设置了一个位,即int变量

问题描述 投票:91回答:18
int temp = 0x5E; // in binary 0b1011110.

有没有这种方法可以检查temp中的第3位是1还是0而没有位移和屏蔽。

只是想知道是否有一些内置功能,或者我自己不得不写一个。

c++ c bit-manipulation
18个回答
146
投票

在C中,如果要隐藏位操作,可以编写一个宏:

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

并以这种方式使用它来检查右端的第n位:

CHECK_BIT(temp, n - 1)

在C ++中,您可以使用std::bitset


4
投票

我用这个:

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

其中“pos”定义为2 ^ n(例如1,2,4,8,16,32 ......)

返回:如果为真,则返回1


3
投票

我试图读取一个32位整数,它定义了PDF中对象的标志,这对我不起作用

修正它的原因是改变了定义:

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

操作数&返回一个整数,其中的标志都是1,并且它没有正确地转换为布尔值,这就是诀窍


2
投票

您可以“模拟”移位和屏蔽:if((0x5e /(2 * 2 * 2))%2)...


2
投票

对于低级x86特定解决方案,请使用x86 TEST操作码。

你的编译器应该把_bittest变成这个......


1
投票

为什么不使用像这样简单的东西?

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


0
投票

如果你只想要一个真正的硬编码方式:

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

注意这个hw依赖并假定这个位顺序为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
投票

虽然现在回答已经很晚了,但是如果设置了Nth位,可以找到一种简单的方法,只需使用POWER和MODULUS数学运算符。

让我们说我们想知道'temp'是否设置了第N位。如果设置了位,则以下布尔表达式将为true,否则为0。

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

请考虑以下示例:

  • int temp = 0x5E; //二进制0b1011110 // BIT 0是LSB

如果我想知道是否设置了第3位,我明白了

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

因此表达式返回true,表示设置了第3位。


0
投票

一种方法是在以下条件下进行检查:

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

-1
投票

最快的方式似乎是掩码的查找表


77
投票

检查是否设置了位N(从0开始):

temp & (1 << N)

没有内置功能。


22
投票

如果它是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);

11
投票

根据this description of bit-fields的说法,有一种直接定义和访问字段的方法。此条目中的示例如下:

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
投票

是的,我知道我没有“这样做”。但我经常写:

    /* 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); }

Ef。:

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 ++);

10
投票

选择的答案实际上做错了什么。以下函数将返回位位置或0,具体取决于该位是否实际启用。这不是海报所要求的。

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

这是海报最初寻找的内容。如果该位有效,则下面的函数将返回1或0,而不是位置。

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

6
投票

5
投票

使用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;
}

4
投票

有,即_bittest内在指令。

© www.soinside.com 2019 - 2024. All rights reserved.