我有三個代表位的bool
值。我想有形式從三個布爾值創建一個整數作爲C++中的位
true true true = 7
false true false = 2
的整數我有
int val = 4*boolVal1 + 2*boolVal2 + boolVal3;
有另一種方式,也許更簡單?
我有三個代表位的bool
值。我想有形式從三個布爾值創建一個整數作爲C++中的位
true true true = 7
false true false = 2
的整數我有
int val = 4*boolVal1 + 2*boolVal2 + boolVal3;
有另一種方式,也許更簡單?
您可能會發現更加清晰使用位運算符,而不是乘法和加法:
比乘法和bitshiftingint val = (boolVal1 << 2) | (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);
爲什麼地球上你會爲此感到困擾?這只是一個更一般的說法,因此您可以稍後更改編碼值,而無需使用實際值觸及潛在分佈式代碼(例如,如果您意識到與某些文件或網絡的格式相比,你需要解析的數據,你可以將它添加到一個地方並重新編譯)。當然,最好只提供一個編碼/解碼功能,如果你添加新的標誌,你仍然需要它。
雖然有Flag1和NotFlag1可能看起來毫無意義,但通常情況下,您有像粘滯和浮動,或男性和女性互斥值的東西,並沒有特別的理由來強制客戶檢查說浮動爲!置頂或女性爲男性等。
'NotFlag'在這裏不是很有幫助。如果你想知道Flag2是否被清除,你仍然會檢查'(value&Flag2)== NotFlag2'。此外,'?:'可能會產生比乘法更慢的代碼(分支與算術運算)。另外,我發現爲這樣的枚舉重載運算符'|','&','^'和'〜'很方便,因此這個類型被保留 - 我甚至有一個宏。 – krlmlr
@ user946850:通常一個函數(特別是C函數)要求調用者對來自標誌的參數進行編碼,因此分佈式調用代碼 - 其中可以有任意數量和「清潔度」因此非常重要,可以或在一起標誌和「NotFlag」非常高興,不需要進行標誌測試 - 這是在被調用函數的實現中整合的步驟,更容易維護。是的,當枚舉被用作客戶端代碼中的適當值時(而不僅僅是爲了編碼參數),正確的操作符值得擁有。 –
或者你可以使用Horner的方法:
int val = (((boolVal1 << 1) | boolVal2) << 1) | boolVal3.
這也使得它更容易添加或刪除語句的中間變量,而無需改變所有其他係數。
但是,這可能對讀者來說不太明顯。
這不是很可能很重要,但我很好奇 - 是否使用通用編譯器 - 由於在評估中有順序排列,它可能會變得更糟:知道它們的任何/所有優化器是否可以生成可以在CPU指令流水線上並行化...... –
@Tony,你必須看看機器代碼,但我希望現代編譯器能夠注意到括號內沒有分支,並且相當乾淨地展開它。 –
如果你知道你也可以使用實現定義和位集,小端版本的存儲方式:
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;
大端版本有位反轉和大量的填充(29位,如果unsigned int
是32位寬)在前面。
只是fyi,不應該「真實的真實」導致7?否則,所有的公式到目前爲止是錯誤的... – SinisterMJ
'int val = 4 * boolVal1 + 2 * boolVal2 + boolVal3;'將給出7當你有真正的真正不是8 –
正確的,我剛貼錯了。 Thx糾正! – tzippy