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

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

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

4

23 回答 23

179

在C语言中,如果你想隐藏位操作,你可以写一个宏:

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

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

CHECK_BIT(temp, n - 1)

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

于 2009-02-07T13:16:29.017 回答
98

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

temp & (1 << N)

没有内置函数。

于 2009-02-07T13:15:09.270 回答
31

如果它是 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);
于 2009-02-07T16:23:02.540 回答
20

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

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

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

#define CHECK_BIT(var,pos) (((var)>>(pos)) & 1)
于 2015-08-06T18:55:20.983 回答
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++);
于 2009-02-07T16:13:10.453 回答
10

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

此外,还有一个警告:

然而,结构中的位成员有实际的缺点。首先,内存中位的顺序取决于体系结构,并且内存填充规则因编译器而异。此外,许多流行的编译器为读取和写入位成员生成效率低下的代码,并且由于大多数机器无法操作内存中的任意位集,因此存在与位域相关的潜在严重线程安全问题(尤其是在多处理器系统上),但必须改为加载和存储整个单词。

于 2009-02-07T13:20:45.997 回答
7

您可以使用 Bitset - http://www.cppreference.com/wiki/stl/bitset/start

于 2009-02-07T13:14:09.630 回答
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;
}
于 2009-02-07T16:23:14.427 回答
4

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

什么修复了它改变了定义:

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

操作数 & 返回一个整数,其标志都在 1 中,并且它没有正确转换为布尔值,这起到了作用

于 2012-05-15T12:51:08.070 回答
4

我用这个:

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

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

返回: 1 如果为真 0 如果为假

于 2018-04-09T04:05:45.617 回答
3

有,即_bittest内在指令。

于 2009-02-07T13:19:35.203 回答
3
#define CHECK_BIT(var,pos) ((var>>pos) & 1)

pos - 从 0 开始的位位置。

返回 0 或 1。

于 2020-03-05T11:50:09.463 回答
2

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

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

于 2009-02-09T16:35:46.873 回答
1

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

于 2009-02-07T13:16:36.147 回答
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

于 2013-10-15T15:37:27.870 回答
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
于 2017-05-25T09:31:51.683 回答
0

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

 #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

于 2009-02-07T14:30:59.380 回答
0

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

假设我们想知道“temp”是否设置了第 N 位。如果设置了位,则以下布尔表达式将为真,否则为 0。

  • (温度模量 2^N+1 >= 2^N)

考虑以下示例:

  • 国际温度 = 0x5E;// 二进制 0b1011110 // BIT 0 是 LSB

如果我想知道是否设置了第 3 位,我会得到

  • (94 模数 16) = 14 > 2^3

所以表达式返回真,表示设置了第 3 位。

于 2013-07-10T08:59:09.463 回答
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();
于 2020-09-22T16:23:15.707 回答
0

先前的答案向您展示了如何处理位检查,但更多情况下并非如此,这都是关于以整数编码的标志,这在任何先例情况下都没有得到很好的定义。

在典型情况下,标志本身被定义为整数,它所指的特定位为 1。在下面的示例中,您可以检查整数是否具有标志列表中的任何标志(连接多个错误标志)或是否每个标志都在整数中(连接多个成功标志)。

以下示例说明了如何处理整数中的标志。

此处提供实时示例: 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;
}
于 2020-09-30T10:23:54.867 回答
0

快速和最佳的宏

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

.
.

if (get_rx_pin_status() == ( 1 << BITX ))
{
    do();
}
于 2021-02-16T18:00:45.473 回答
-1

我做这个:

LATGbits.LATG0=((m&0x8)>0); //检查m的bit-2是否为1

于 2020-01-16T14:17:43.197 回答
-2

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

于 2010-11-23T10:37:56.043 回答