当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《C/C++检查是否设置了一个位,即int变量》经验,为你挑选了8个好方法。

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

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

并以这种方式使用它:

CHECK_BIT(temp, n - 1)

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



1> mouviciel..:

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

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

并以这种方式使用它:

CHECK_BIT(temp, n - 1)

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


@Eduard:在C中,所有`!= 0`都是真的,为什么要这么麻烦?`1`与`0.1415`完全一样!
呃,`std :: bitset`,真的吗?当然,不是做一点工作(可能还有一些非常好的模板)来检查一个位,而是使用一个膨胀的容器来存储(在我的实现中)每个'bit'在一个原本未使用的`unsigned long`中.多么浪费空间!
如果你需要一个简单的真值,它应该是!!((var)&(1 <<(pos))).
确实使用std :: bitset.
在C中这很好.但是这种C++中的宏.那是可怕的,如此开放的滥用.使用std :: bitset

2> Joao da Silv..:

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

temp & (1 << N)

没有内置功能.


提及它的+1从0开始,因为我怀疑OP正在考虑从1开始,接受的答案会让他遇到麻烦.:)
好的,我知道了.我们从0号开始,即"1 << 0",它是1,没有任何移位(移位0),这是"1 << 0 == 1"

3> user21714..:

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

typedef std::bitset IntBits;
bool is_set = IntBits(value).test(position);

或者这种愚蠢

template
struct pow_2 {
    static const unsigned int value = 2 * pow_2::value;
};

template<>
struct pow_2<0> {
    static const unsigned int value = 1;
};

template
bool is_bit_set(unsigned int value)
{
    return (value & pow_2::value) != 0;
} 

bool result = is_bit_set<2>(value);


@ user21714我想你的意思是std :: bitset <8*sizeof(int)>
upvote for template metaprogramming approach :)

4> shocker92..:

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

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

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

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



5> gimel..:

根据位域的这种描述,存在一种用于直接定义和访问字段的方法.此条目中的示例如下:

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

此外,还有一个警告:

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



6> Mr.Ree..:

是的,我知道我没有"这样做".但我经常写:

    /* Return type (8/16/32/64 int size) is specified by argument size. */
template inline TYPE BIT(const TYPE & x)
{ return TYPE(1) << x; }

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



7> yawmark..:

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



8> Martin York..:

使用std :: bitset

#include 
#include 

int main()
{
    int temp = 0x5E;
    std::bitset   bits(temp);

    // 0 -> bit 1
    // 2 -> bit 3
    std::cout << bits[2] << std::endl;
}


是的,但是我认为发问者(和来自Google搜索的人)可能没有这种能力,您的回答可能会误导他们。
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有