我有bool
三个代表位的值。我想有一个整数形式
true true true = 7
false true false = 2
我有
int val = 4*boolVal1 + 2*boolVal2 + boolVal3;
还有另一种方法,也许更简单?
您可能会发现使用按位运算符而不是乘法和加法更清楚:
int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3;
或者你可以使用霍纳的方法:
int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.
这也使得在语句中间添加或删除变量更容易,而无需更改所有其他系数。
然而,这对读者来说可能不太明显。
除了乘法和位移之外,您还可以使用枚举来记录关系。通常不值得努力,但只是为了完整性......
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 等。
如果您知道字节序,您还可以使用实现定义的行为和位集,小字节序版本:
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 int
big-endian 版本的位颠倒了,前面有很多填充(如果是 32 位宽,则为 29 位)。