2011-09-14 31 views
1

我有一個32字節的字節數組,其中每個字節(0到3)的前4位表示1到128之間的數字的置位或取消置位狀態。例如,If我給了數字3,我需要在數組的第一個字節中設置位2。如果給出數字9,我需要設置數組中第三個字節的第0位。我遇到的問題是在C#中找到明智的方法來做到這一點。我確信必須有一種簡單的方法來做數學運算,但到目前爲止還沒有找到方法。雖然我在這個問題上撓頭,但我想我會看看是否有人能提出一些建議。使用C#設置字節數組中的位

---------更新-------------------

根據所給出的答案,我已經制作了以下功能。這正是我所需要的。我可能沒有在我的問題中明確說明我需要什麼,但已經給了我足夠的建議以找到正確的代碼。

// outputNumber = number passed into this function 

byte[] bytes = new byte[32]; 

int bit = (outputNumber - 1) % 4; 

byte byteSetting = (byte)(1 << bit); 

bytes[(outputNumber - 1)/4] |= byteSetting; 

回答

1
int byt = bitNumber/4; // You could do byt = bitNumber >> 2 
int bit = bitNumber % 4; // You could do bit = bitNumber & 3 

bytes[byt] |= (byte)(1 << bit); 

哪裏bytes是你的字節數組。

重置密碼:

bytes[byt] &= (byte)(byte.MaxValue^(1 << bit)); 

要讀取字節的值:

var res = bytes[byt] & (byte)(1 << bit) 

(如果你有興趣,^是XOR運算符)

+0

這個答案對我的幫助最大,因爲它考慮到了我需要在數組中設置不同字節的位而不是固定字節。 – Retrocoder

2

您可以設置像這樣的陣列中的每個字節中的位:

array[2] |= (byte)(1<<3); // set bit #4/index 3 in array element #3/index 2 

您可以清除有點像這樣:

array[2] &= unchecked((byte)(~(1<<3))); // clear the same bit we set previously 
1

類似需要的東西。在64位系統上使用ulongs(32位 - > uint)而不是字節。性能差異非常顯着。

public struct BitField { 

    private ulong[] _Values; 

    private BitField(ulong[] values) { 
     _Values = values; 
    } 

    public static BitField New() { 
     return new BitField(new ulong[] { 0ul, 0ul }); 
    } 

    public BitField Clone() { 
     return new BitField(new ulong[] { _Values[0], _Values[1] }); 
    } 

    public void Clear() { 
     _Values[0] = ulong.MinValue; 
     _Values[1] = ulong.MinValue; 
    } 

    public void SetAll() { 
     _Values[0] = ulong.MaxValue; 
     _Values[1] = ulong.MaxValue; 
    } 

    public void AND_Combine(BitField bitField) { 

     _Values[0] &= bitField._Values[0]; 
     _Values[1] &= bitField._Values[1]; 
    } 

    public void OR_Combine(BitField bitField) { 

     _Values[0] |= bitField._Values[0]; 
     _Values[1] |= bitField._Values[1]; 
    } 

    public bool Intersects(BitField bitField) { 

     if ((_Values[0] & bitField._Values[0]) > 0) { 
      return true; 
     } 
     else { 
      if ((_Values[1] & bitField._Values[1]) > 0) { 
       return true; 
      } 
      else { 
       return false;         
      } 
     } 
    } 

    public bool this[int index] { 
     get { 
      if (index > 127 || index < 0) { 
       return false; 
      } 
      int item = index >> 6; 
      int bit = index % 64; 

      ulong compare = 1ul << bit; 
      return ((_Values[item] & compare) == compare); 
     } 
     set { 
      if (index >= 0 || index < 128) { 
       int item = index >> 6; 
       int bit = index % 64; 
       ulong compare = 1ul << bit; 

       if (value) { 
        _Values[item] |= compare; 
       } 
       else { 
        _Values[item] &= ~compare; 
       } 
      } 
     } 
    } 
}