2017-04-20 271 views
-1

的第14位讀取所有對位檔/屏蔽的問題和答案後,我根本就不能換我的頭周圍。我只是不理解它是如何在基礎層面上工作的。我已經能夠通過使用BitArray和BitConverter,而不是實現各種技術,但我真的想了解位檔/屏蔽更好。C# - 獲取特定位並獲取一個USHORT值

具體需要我必須要做到以下幾點:

我有一個USHORT:0x810E(33038)

使用位檔/屏蔽,我想知道如何:

  • 獲得第16位結果:1
  • 獲得第15位結果:0
  • 獲得一定範圍內的比特來創建一個新USHORT值,特別是 第14位結果:270

正如我所說的,我能夠進行使用BitArray是如何將這些任務我已經得到了正確的結果,但我想了解如何執行使用比特移位/屏蔽這些操作。

任何幫助,將不勝感激。

回答

1

屏蔽單位

正如你可能知道,ushort是一個16位的值,所以你一定數目0x810E也可能是因爲不存在用於移動運營商寫成

‭10000001 00001110‬ 

ushort,該值首先轉換爲int

所以,如果你想獲得的第15位,你可以採取單個位

000000000 0000000 00000000 00000001 

倍和14倍接班向左(右充滿0

00000000 00000000 01000000 00000000 

並且您已創建位掩碼。現在

,如果你結合面罩和值與按位and,你會得到第15位的唯一值:

‭00000000 00000000 10000001 00001110‬ 
& 00000000 00000000 01000000 00000000 
= 00000000 00000000 00000000 00000000 

這是0一次。要訪問此位,你就必須將整個結果移回到正確的14倍和到一個ushort

ushort value_15 = (ushort)(((1 << 14) & value) >> 14); 

我們可以做得更好:

這可以用下面的代碼來表示?

雖然這種方法似乎是正確的,但有一個簡單的方法來做到這一點:原來的值右移14倍 (結果爲00000000 00000000 00000000 00000010,左側充滿0),並進行簡單的逐位&1

00000000 00000000 00000000 00000000 00000000 00000010 
& 00000000 00000000 00000000 00000000 00000000 00000001 
= 00000000 00000000 00000000 00000000 00000000 00000000 

這導致C#在:

ushort value_15 = (ushort)((value >> 14) & 1); 

所以你避免一個額外的位移和使用 符號數時(因爲那裏的最高位,用於標誌,保持不變通過移動),我們得到相同的結果甚至。

掩蔽位範圍

要屏蔽一個位範圍,所有你需要做的是改變你的面具。因此,要獲得低14位的值,你可以用的面膜

00000000 00000000 ‭10000001 00001110‬ 
& 00000000 00000000 00111111 11111111 
= 00000000 ‭00000000 00000001 00001110 

C#這可以用

ushort first14bits = (ushort)((0xFFFF >> 2) & value); 

哪裏來表示(0xFFFF00000000 00000000 11111111 11111111)。

+1

字節順序是這裏只是一個分心。它與位掩碼整數值無關,而且可能會讓那些無法對位級操作進行一些研究的人感到困惑。語法和操作完全相同,無論單個整數值的長度如何,也不管平臺的字節順序如何。而且,當一個人能夠滿足時,這樣做是浪費,而且更不「理解」兩班倒。它只是使代碼重複而且難以閱讀。 –

+1

此外,有使用兩個移的方法,它可能導致一個天真程序員導致被移動爲第二移位一個符號值的實現中,這可能在新的一組比特填充(在這些場景場景中,另一種方法是投如'1 << 63'到'ulong',但是這需要應用'unchecked'的代碼,這是人誰需要比特移位首先向他們解釋)的可能性較小。單班實施可以避免這種情況,因爲您(在OP的代碼中)以無符號的值開始,所以沒有符號位被移位填入。 –

+0

我已經刪除了關於endianess的部分。我試圖創建一個詳盡的答案,但我承認,也許我專注於不相關的細節。我現在沒有時間了,也許我會在稍後改變答案。我知道的一件事(因爲我沒有意識到)鑄件是必需的。 – ventiseis