2015-12-14 55 views
4

我有一個名爲Forced的uint,包含32位。將位域轉換爲數組

我做的東西,如:

if(Forced & 512) 
    doStuff(); 

我在找做的就是把被迫進入一個數組,然後會變成:

if(ForcedArray[(int)Math.Log(512,2)]) 
    doStuff(); 

有沒有在.NET中的便捷方法做這個?將位域轉換爲數組的方法是什麼?

+7

爲什麼?像<< Forced&(1 << bitNumber)'這樣的'<<'來訪問比特是微不足道的...... –

回答

3

你可以寫這種擴展方法:

public static class UIntExtensions 
{ 
    public static bool IsBitSet(this uint i, int bitNumber) 
    { 
     return i & (1 << bitNumber) != 0; 
    } 
} 

或者,如果你想這樣做的C#6路:

public static class UIntExtensions 
{ 
    public static bool IsBitSet(this uint i, int bitNumber) => (i & (1 << bitNumber)) != 0; 
} 

這是很容易從代碼中使用:

if(Forced.IsBitSet((int)Math.Log(512,2))) 
    doStuff(); 

顯然,需要添加一些檢查位數> = 0或< = 31,但您明白了。

3

使用位移來訪問整數Forced & (1 << bitNumber)的位聽起來像一個很好的方法(很好的函數包裝訪問顯示在Ron Beyer's answer)。

大多數讀者的代碼會被這種緊湊的單字字段轉換成像數組這樣複雜的數據結構的困惑。除非有其他原因(如JSON序列化之類的外部API約束)或顯着的可讀性增益,否則請考慮避免這種情況。

作爲中間方法,您可以創建小型包裝結構來保存整數值,並額外公開每個位(最好是不可變)的索引訪問。

如果你真的想和array - basic for循環或LINQ可以用來將每一位轉換爲布爾值。即如果它僅僅是一個整數(可能需要調整順序根據這一點,你需要首先,這個人把最低位在前):

var array = Enumerable.Range(0, 32) 
    .Select(bitNumber => (Forced & (1 << bitNumber)) !=0) 
    .ToArray(); 
+0

比特數組的合法用途通常是微性能優化和/或內存使用。不確定我會建議Linq的答案,因爲它可能會使微優化帶來的任何收益失效。然後再次,位陣列可能被用於許多情況下,這種優化是沒有必要的... –

+1

@EricJ。我嚴重懷疑OP是在尋找微型優化 - '(int)Math.Log(512,2)'看起來不像在性能敏感的代碼中使用的任何東西。可能是其他原因 - 也許使用數組可以使特定代碼更具可讀性? (再次,如果性能/大小問題,可以將整數轉換爲帶有索引器的結構) –

+0

也許不是OP,但我只是閱讀http://stackoverflow.com/q/21877966/141172,它提醒我人們有一種習慣複製和使用他們不完全理解的代碼。出於這個原因,我更喜歡Ron給出的答案,或者你真的是在這個問題下的評論。 –

0
public static class UIntExtensions 
{ 
    public static byte[] GetBitArray(this uint v) 
    { 
     var r = byte[32]; 
     for (var i = 0; i < 32; ++i) 
     { 
      r[i] = v & 1; 
      v = v >> 1 
     } 
     return r; 
    } 
} 
+0

你能解釋一下你的代碼嗎?特別是,你會如何回答這個問題:「什麼是將位域轉換爲數組的方便方式?」?你應該知道你的答案在[刪除隊列]中(http://stackoverflow.com/review/low-quality-posts/10561061)。 –