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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/523724/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:46:37  来源:igfitidea点击:

C/C++ check if one bit is set in, i.e. int variable

c++cbit-manipulation

提问by Milan

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

Is there such a way to check if bit 3 in temp is 1 or 0 without bit shifting and masking.

有没有这样一种方法可以在不进行位移和屏蔽的情况下检查 temp 中的第 3 位是 1 还是 0。

Just want to know if there is some built in function for this, or am I forced to write one myself.

只是想知道是否有一些内置函数,还是我被迫自己写一个。

回答by mouviciel

In C, if you want to hide bit manipulation, you can write a macro:

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

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

and use it this way to check the nthbit from the right end:

并用这种方式检查右端的n位:

CHECK_BIT(temp, n - 1)

In C++, you can use std::bitset.

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

回答by Joao da Silva

Check if bit N (starting from 0) is set:

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

temp & (1 << N)

There is no builtin function for this.

没有为此的内置函数。

回答by user21714

I would just use a std::bitset if it's C++. Simple. Straight-forward. No chance for stupid errors.

如果是 C++,我只会使用 std::bitset。简单的。直截了当。没有机会犯愚蠢的错误。

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

or how about this silliness

或者这个愚蠢怎么样

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

回答by shocker92

What the selected answer is doing is actually wrong. The below function will return the bit position or 0 depending on if the bit is actually enabled. This is not what the poster was asking for.

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

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

Here is what the poster was originally looking for. The below function will return either a 1 or 0 if the bit is enabled and not the position.

这就是海报最初要寻找的东西。如果启用了位而不是位置,则下面的函数将返回 1 或 0。

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

回答by Mr.Ree

Yeah, I know I don't "have"to do it this way. But I usually write:

是的,我知道我“不必”这样做。但我通常写:

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

E.g.:

例如:

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

Amongst other things, this approach:

除其他外,这种方法:

  • Accommodates 8/16/32/64 bit integers.
  • Detects IsBitSet(int32,int64) calls without my knowledge & consent.
  • Inlined Template, so no function calling overhead.
  • const&references, so nothing needsto be duplicated/copied. And we are guaranteed that the compiler will pick up any typo's that attempt to change the arguments.
  • 0!=makes the code more clear & obvious. The primary point to writing code is always to communicate clearly and efficiently with other programmers, including those of lesser skill.
  • While not applicable to this particular case... In general, templated functions avoid the issue of evaluating arguments multiple times. A known problem with some #define macros.
    E.g.: #define ABS(X) (((X)<0) ? - (X) : (X))
          ABS(i++);
  • 容纳 8/16/32/64 位整数。
  • 在我不知情和同意的情况下检测 IsBitSet(int32,int64) 调用。
  • 内联模板,因此没有函数调用开销。
  • 常量和参考,所以没有什么需要被复制/复制。我们保证编译器会发现任何试图改变参数的错字。
  • 0!=使代码更加清晰和明显。编写代码的主要目的始终是与其他程序员(包括技能较低的程序员)进行清晰有效的沟通。
  • 虽然不适用于这种特殊情况……一般来说,模板化函数避免了多次评估参数的问题。一些#define 宏的已知问题。
    例如:#define ABS(X) (((X)<0) ? - (X) : (X))
          ABS(i++);

回答by gimel

According to this description of bit-fields, there is a method for defining and accessing fields directly. The example in this entry goes:

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

Also, there is a warning there:

此外,那里有一个警告:

However, bit members in structs have practical drawbacks. First, the ordering of bits in memory is architecture dependent and memory padding rules varies from compiler to compiler. In addition, many popular compilers generate inefficient code for reading and writing bit members, and there are potentially severe thread safety issues relating to bit fields (especially on multiprocessor systems) due to the fact that most machines cannot manipulate arbitrary sets of bits in memory, but must instead load and store whole words.

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

回答by yawmark

回答by Martin York

Use std::bitset

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

回答by Dave Van den Eynde

There is, namely the _bittestintrinsic instruction.

有,即_bittest内在指令。

回答by AnthropicDream

I use this:

我用这个:

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

where "pos" is defined as 2^n (i.g. 1,2,4,8,16,32 ...)

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

Returns: 1 if true 0 if false

返回: 1 为真 0 为假