12

我有bool三个代表位的值。我想有一个整数形式

true true true = 7
false true false = 2

我有

int val = 4*boolVal1 + 2*boolVal2 + boolVal3;

还有另一种方法,也许更简单?

4

4 回答 4

27

您可能会发现使用按位运算符而不是乘法和加法更清楚:

int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3; 
于 2012-07-03T12:36:52.363 回答
5

或者你可以使用霍纳的方法:

int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.

这也使得在语句中间添加或删除变量更容易,而无需更改所有其他系数。

然而,这对读者来说可能不太明显。

于 2012-07-03T12:53:12.527 回答
4

除了乘法和位移之外,您还可以使用枚举来记录关系。通常不值得努力,但只是为了完整性......

enum Encoding
{ 
    Flag3 = 1,      NotFlag3 = 0,
    Flag2 = 1 << 1, NotFlag2 = 0,
    Flag1 = 1 << 2, NotFlag1 = 0
};

int val = (boolVal1 ? Flag1 : NotFlag1) |
          (boolVal2 ? Flag2 : NotFlag2) |
          (boolVal3 ? Flag3 : NotFlag3);

你到底为什么要为此烦恼?它只是更通用一点,因此您可以稍后更改 Encoding 值,而不必使用实际值触及潜在的分布式代码(例如,如果您意识到与某些文件或网络的格式相比,您会遗漏一点您需要解析的数据,您可以将其添加到一个地方并重新编译)。当然,最好还是只提供一个编码/解码功能,如果您要添加新标志,您仍然需要它。

虽然拥有 Flag1 和 NotFlag1 可能看起来毫无意义,但通常情况下,您具有相互排斥的值,例如 Sticky 和 ​​Floating,或 Male 和 Female,并且没有特别的理由强迫客户检查说 Floating 为 !Sticky 或 Female如 !Male 等。

于 2012-07-03T12:45:17.037 回答
2

如果您知道字节序,您还可以使用实现定义的行为和位集,小字节序版本:

union foo {
        unsigned int the_int;
        struct {
                unsigned int bit3:1
                unsigned int bit2:1
                unsigned int bit1:1
        };
};

然后设置它们:

foo.bit1 = true;
foo.bit2 = false;
foo.bit3 = true;

并阅读:

foo.the_int;

unsigned intbig-endian 版本的位颠倒了,前面有很多填充(如果是 32 位宽,则为 29 位)。

于 2012-07-03T13:49:49.433 回答