将一组布尔值转换为数字

时间:2010-08-09 20:07:18

标签: c++ bit-manipulation

这是我将用来获取一组三个布尔值并将其转换为用于switch语句的int的代码:

int bits = 0;
bool a = true, b = false, c = true;  // 101 = 5

bits = bits | a << 2;
bits = bits | b << 1;
bits = bits | c;

cout << bits;

根据这三种布尔值的总和状态,我有八种情况。我这样做了吗?

是的,不是语法意义上的,如果有任何问题请指教。更正确的是“这是解决这个问题的最好方法吗?”

6 个答案:

答案 0 :(得分:4)

如果您使用的是C ++,则可以使用bitset<N>

答案 1 :(得分:1)

你做得对。你可以使代码更简洁:

bits |= (a<<2) | (b<<1) | (c<<0);

请注意,标准不对bool强制执行任何大小限制。实际上,三位应该没有问题,但是标准不会在这里支持你。

答案 2 :(得分:1)

$ cat ttt.c

//example of C solution
#include <stdio.h>

int main() {
        union {
                unsigned int val;
                struct {
                        unsigned a : 1;
                        unsigned b : 1;
                        unsigned c : 1;
                        //unsigned d : 1; 
                        //e, f, g, h...
                } flags;
        } bits;

        bits.val=0;
        bits.flags.a = 1;
        bits.flags.c = 1;

        printf("val: %d\n",bits.val);
        return 0;
}

〜$ ./ttt

val: 5

答案 3 :(得分:0)

您可以随时明确地进行转换:

bits = bits | (a ? 1 : 0) << 2;

但是我相信一旦你使用了位移运算符,C / C ++就会隐式处理它。

您应该为每个标志定义常量,为您设置的位指定名称:

const int a_flag = 2;
bits = bits | (a ? 1 : 0) << a_flag;

修改

从我对答案的评论中可以看出,大多数C / C ++程序员更喜欢学习隐式转换和运算符优先级。因此,您的原始代码是“最正确的”。

编辑2:

除此之外,您应该使用|=运算符:

const int a_flag = 2;
bits |= a << a_flag;

答案 4 :(得分:0)

我会这样做:

bits = (bits << 1) | a;
bits = (bits << 1) | b;
bits = (bits << 1) | c;

如果您需要添加或删除标记,则需要较少的维护工作。

然而,这样做是为了让你可以将它用于switch听起来像是一个坏主意。添加标志会使您需要处理的状态数量翻倍,case值将变得脆弱且难以阅读。

但如果你真的必须,这是另一种方法:

enum
{
    c_bit_offset,
    b_bit_offset,
    a_bit_offset
};

unsigned int bits =   (a << a_bit_offset)
                    | (b << b_bit_offset)
                    | (c << c_bit_offset);
switch (bits)
{
    case 0:
       /* Do something. */
       break;
    case (1 << a_bit_offset):
       /* Do something. */
       break;
    case (1 << a_bit_offset) | (1 << b_bit_offset):
       /* Do something. */
       break;
    ...
}

顺便说一下,您可能应该使用unsigned int而不是int

答案 5 :(得分:0)

您可以制作一些定义以便于使用位

#define BitSet(arg,bit) ((arg) |= (1<<bit))
#define BitClr(arg,bit) ((arg) &= ~(1<<bit)) 
#define BitFlp(arg,bit) ((arg) ^= (1<<bit)) 
#define BitTst(arg,bit) ((arg) & (1<<bit)) 

然后你只能使用一个字符

keys = 0b00000101;
BitSet (keys,1);

这是在嵌入式系统中工作的常用方法。