2016-02-01 48 views
0

我有一個決策樹,使用位和來確定分支。比較位和時會產生什麼影響?

例如: 如果我們有規則:1,2,4,8,16 總和取決於:if true then sum + = ruleId。

分支功能,而不是做:

if(sum == 23) => 
else if(sum == 15) => 

採用的是按位與:

if(sum & 23 == 23) => 
else if(sum & 15 == 15) => 

有什麼用位AND和==之間的區別?

我需要做的是生成一個List<Tuple<int,boo>>,這將導致給定的結果評估爲真。我的想法是要做到: 23,例如:

1 && 2 && 4 && 8 && !16 

將導致其評價爲真。但是,按比例「與」對此有什麼影響?我需要改變什麼才能正確輸出將導致它爲真的表達式?

+2

請注意'&&'只適用於'bool'。 – juharr

+0

@DrewJordan - 我以爲我說'''是加法。我可能錯誤地打錯了。無論如何評論刪除。 – Jamiec

+1

我建議你更多地解釋你的要求。你說你有一套規則。因此,如果要求執行每個規則,如果它已被選中。那麼對於'23'你會執行規則1,2,4和16? – musefan

回答

2

爲什麼要使用按位運算?在你提到的特定情況下,這並不重要(只要你將AND包裝在中提到)。

但是,如果稍有不同,會發生什麼?例如,如果新開發人員稍後出現並且必須添加案例,並且不瞭解其工作原理。他們補充下位(32或100000),並添加自己的支票給if S的底部

if((sum & 23) == 23) => 
else if((sum & 15) == 15) => 
//... 
else if((sum & 31) == 31) => 

會發生什麼?

那麼,在二進制& 31(按位與)23二進制:

11111 
10111 
----- 
10111 

嗯哦!評估爲真!而且,由於他們不知道更好,所以將其添加到底部,23首先評估爲TRUE,而31則從未評估。

因此,它成爲你的意圖的問題。如果這是預期的行爲(我懷疑它),那麼你可以使用按位操作,並且你會一直知道,如果你檢查對象,例如23,你檢查那些特定的位被設置,而不是他們是唯一的位。如果您想知道是否只設置了23中的所有位,請使用(sum == 23)。

+0

我喜歡這個答案,它有我的名字在裏面......還有一個關於確保它做它應該做的事情的好處。如果我在猜測我會傾向於這樣做的意圖應該是一系列if語句(沒有'else')。所以,如果這個規則已經設置然後執行它,並重復每個規則 – musefan

0

只有當總和等於您測試的值時,相等運算符纔會爲真。按位檢查將確保將該數字表示的所有位都設置爲您的值。

例如

總和= 23(10111),則總和== 23將是如此,因爲將總結& 23 == 23

總和= 25(11001),則總和== 23將是錯誤的,但總結& 23現在返回17

11001 
& 10111 
====== 
    10001 (17) 
+1

你最好找一個'sum&23'爲'23'的例子。那麼你可以看到一個是假的而另一個是真的 – musefan

3

有什麼用位AND和==之間的區別?

那麼==檢查兩個值是否相等,很簡單。按位AND計算比特匹配的值。當它與等號檢查組合在一起時,則您正在有效地檢查sum是否具有與23使用相同的位。

更容易,如果你寫下來的比特瞭解,可以說sum = 31

0001 1111 // (sum 31) 
& 0001 0111 // (23) 
= 0001 0111 // (only set 1 if *both* are 1) 

通知你結束了一樣23所以當你(sum & 23) == 23true。這樣做的目的是檢查是否設置了特定的位。在23的情況下,您正在檢查是否設置了位16,4,2和1。

"C# Bit Flags"是一個有用的搜索詞,如果你想了解更多信息。

注意,你需要使用周圍的位與作爲優先順序括號將嘗試評估==第一:

if((sum & 23) == 23) 

這是什麼,你可能會試圖純屬猜測如果你試圖執行已設置的每個規則,那麼你可能想要類似這樣的東西:

if((sum & 1) == 1) 
    ExecuteRule1(); 
if((sum & 2) == 2) 
    ExecuteRule2(); 
if((sum & 4) == 4) 
    ExecuteRule4(); 
if((sum & 8) == 8) 
    ExecuteRule8(); 
if((sum & 16) == 16) 
    ExecuteRule16(); 

使用此代碼,在sum = 23的情況下,它將執行規則1,2,4和16.但會跳過規則8.

0

當您選擇多個位時,您需要進一步比較(如==)。因此

if (sum & 020) 

選擇只有一個位。無論是關閉還是關閉。

if (sum & 017) 

選擇最後四位,但如果任何這些位設置的值爲true。

if ((sum & 017) == 017) 

選擇最後四位,並且所有位必須爲表達被設置爲真。

但是,這些測試都沒有看到可能設置的其他位。如果要斷言,一些位設置和其他人都沒有,你會得到更多的複雜的測試:

if ((sum & 017) == 017 && !(sum & 060)) 

在某些時候,你過到那裏是你的意圖更清晰的表達做相等比較比一個掩碼。

順便說一句,你會注意到我正在使用八進制常量。 八位或十進制更容易使用並維護位掩碼(IMO)。

+0

我想你的例子在試圖解釋它的時候非常混亂。我也不認爲'選擇最後四位,但如果任何一個位被設置爲「正確」,則評估爲真。所有4位需要設置爲true,而不是*其中的任何* – musefan

+0

並非如此。例如,'022&017'的計算結果爲02,非零,所以'if(022&017)'將評估爲真。 –

+0

對不起,我雖然那個評論指的是'if((sum&017)== 017)'代碼。如果我們正在談論你的前兩個例子,那麼它是無關緊要的,因爲他們甚至不會編譯 – musefan

相關問題