[英]Get a specific bit from byte
我有一個字節,特別是字節數組中的一個字節,該字節數組是通過另一設備發送的UDP傳入的。 該字節存儲設備中8個繼電器的開/關狀態。
如何獲得所述字節中特定位的值? 理想情況下,擴展方法看起來最優雅,而返回布爾值對我來說最有意義。
public static bool GetBit(this byte b, int bitNumber)
{
//black magic goes here
}
簡單。 使用按位與將您的數字與2 ^ bitNumber進行比較,該值可以通過移位來廉價地計算。
//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;
編輯:要添加更多的細節,因為有很多類似的答案而沒有解釋:
逐位AND使用AND聯接逐位比較每個數字,以產生一個數字,該數字是在該位置的第一位和第二位都被設置的位的組合。 這是“半字節”中AND邏輯的邏輯矩陣,顯示了按位AND的操作:
0101
& 0011
----
0001 //Only the last bit is set, because only the last bit of both summands were set
在您的情況下,我們將您傳遞的數字與僅包含您要查找的位的數字進行比較。 假設您正在尋找第四位:
11010010
& 00001000
--------
00000000 //== 0, so the bit is not set
11011010
& 00001000
--------
00001000 //!= 0, so the bit is set
移位確實是我們想要比較的數字,聽起來像是:將數字表示為一組位,然后將這些位左移或右移一定數量。 由於這些是二進制數,因此每個位的位數都是比其右邊的位數大一的2的冪,因此向左移位等於對每個移位的位置加倍該數字,即等於將該數字乘以2 ^ x。 在您的示例中,尋找第四位,我們執行:
1 (2^0) << (4-1) == 8 (2^3)
00000001 << (4-1) == 00001000
現在,您知道它是如何完成的,在低層發生了什么以及為什么起作用。
雖然閱讀和理解Josh的答案很好,但是使用Microsoft為此目的提供的類可能會更高興: System.Collections.BitArray在.NET Framework的所有版本中都可用。
這個
public static bool GetBit(this byte b, int bitNumber) {
return (b & (1 << bitNumber)) != 0;
}
我認為應該這樣做。
另一種方式:)
return ((b >> bitNumber) & 1) != 0;
使用BitArray類並按照OP的建議使用擴展方法:
public static bool GetBit(this byte b, int bitNumber)
{
System.Collections.BitArray ba = new BitArray(new byte[]{b});
return ba.Get(bitNumber);
}
這比0.1毫秒的工作速度更快。
return (b >> bitNumber) & 1;
嘗試這個:
return (b & (1 << bitNumber))>0;
該方法是將另一個字節與按位AND一起使用以屏蔽目標位。
我在這里的類中使用約定,其中“ 0”是最高有效位,“ 7”是最低有效位。
public static class ByteExtensions
{
// Assume 0 is the MSB andd 7 is the LSB.
public static bool GetBit(this byte byt, int index)
{
if (index < 0 || index > 7)
throw new ArgumentOutOfRangeException();
int shift = 7 - index;
// Get a single bit in the proper position.
byte bitMask = (byte)(1 << shift);
// Mask out the appropriate bit.
byte masked = (byte)(byt & bitMask);
// If masked != 0, then the masked out bit is 1.
// Otherwise, masked will be 0.
return masked != 0;
}
}
試試下面的代碼。 與其他帖子的不同之處在於,您可以使用mask( field
)來設置/獲取多個位。 例如,第4位的掩碼可以是1 << 3或0x10。
public int SetBits(this int target, int field, bool value)
{
if (value) //set value
{
return target | field;
}
else //clear value
{
return target & (~field);
}
}
public bool GetBits(this int target, int field)
{
return (target & field) > 0;
}
**范例**
bool is_ok = 0x01AF.GetBits(0x10); //false
int res = 0x01AF.SetBits(0x10, true);
is_ok = res.GetBits(0x10); // true
[Flags]
enum Relays : byte
{
relay0 = 1 << 0,
relay1 = 1 << 1,
relay2 = 1 << 2,
relay3 = 1 << 3,
relay4 = 1 << 4,
relay5 = 1 << 5,
relay6 = 1 << 6,
relay7 = 1 << 7
}
public static bool GetRelay(byte b, Relays relay)
{
return (Relays)b.HasFlag(relay);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.