我有三个代表位的bool
值。我想要一个
true true true = 7
false true false = 2
我有
int val = 4*boolVal1 + 2*boolVal2 + boolVal3;
还有其他方式,甚至可能更简单吗?
答案 0 :(得分:27)
您可能会发现使用按位运算符而不是乘法和加法更清楚:
int val = (boolVal1 << 2) | (boolVal2 << 1) | boolVal3;
答案 1 :(得分:5)
或者你可以使用Horner的方法:
int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.
这也可以更容易地从语句中间添加或删除变量,而不必更改所有其他系数。
但是,这对读者来说可能不太明显。
答案 2 :(得分: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);
为什么你会为此烦恼呢?它只是更加通用,因此您可以在以后更改编码值,而无需使用实际值触摸可能分布的代码(例如,如果您意识到您与您需要解析的某些文件或网络数据的格式,您可以只在一个地方添加它并重新编译)。当然,最好只提供一个编码/解码功能,如果您要添加新标记,您仍然需要它。
虽然拥有Flag1和NotFlag1可能看起来毫无意义,但通常情况下你会有类似互斥的价值观,例如Sticky和Floating,或者男性和女性,并且没有特别的理由要强迫客户检查说漂浮为!粘性或女性为!男性等..
答案 3 :(得分:2)
如果你知道字节序,你也可以使用实现定义的行为和bitset,little-endian版本:
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;
big-endian版本的位反转,前面有很多填充(如果unsigned int
为32位宽,则为29位)。