我有一个字节,特别是来自字节数组的一个字节,它通过从另一个设备发送的UDP进入.该字节存储器件中8个继电器的开/关状态.
如何获取所述字节中特定位的值?理想情况下,扩展方法看起来最优雅,返回bool对我来说最有意义.
public static bool GetBit(this byte b, int bitNumber)
{
//black magic goes here
}
Run Code Online (Sandbox Code Playgroud)
Kei*_*thS 157
简单.使用按位AND将您的数字与值2 ^ bitNumber进行比较,这可以通过位移来便宜地计算.
//your black magic
var bit = (b & (1 << bitNumber-1)) != 0;
Run Code Online (Sandbox Code Playgroud)
编辑:添加更多细节,因为有很多类似的答案,没有解释:
按位AND使用AND连接逐位比较每个数字,以产生一个数字,该数字是位置的组合,其中该位置的第一位和第二位都被设置.这是"半字节"中AND逻辑的逻辑矩阵,它显示了按位AND的操作:
0101
& 0011
----
0001 //Only the last bit is set, because only the last bit of both summands were set
Run Code Online (Sandbox Code Playgroud)
在您的情况下,我们将您传递的数字与仅包含您要查找的位的数字进行比较.假设您正在寻找第四位:
11010010
& 00001000
--------
00000000 //== 0, so the bit is not set
11011010
& 00001000
--------
00001000 //!= 0, so the bit is set
Run Code Online (Sandbox Code Playgroud)
比特移位,产生我们想要比较的数字,正如它听起来的那样:取数字,表示为一组比特,并将这些比特向左或向右移动一定数量的位置.因为这些是二进制数,因此每个位是比其右边的位更大的二次幂,向左移位相当于每个移位的位置加倍一次,相当于将数字乘以2 ^ x的.在您的示例中,查找第四位,我们执行:
1 (2^0) << (4-1) == 8 (2^3)
00000001 << (4-1) == 00001000
Run Code Online (Sandbox Code Playgroud)
现在你知道它是如何完成的,在低层发生了什么,以及它为什么会起作用.
Ben*_*igt 51
虽然阅读和理解Josh的答案是好的,但是你可能会更乐意使用Microsoft为此目的提供的类:System.Collections.BitArray 它可用于所有版本的.NET Framework.
Jos*_*osh 36
这个
public static bool GetBit(this byte b, int bitNumber) {
return (b & (1 << bitNumber)) != 0;
}
Run Code Online (Sandbox Code Playgroud)
应该这样做,我想.
这样做的另一种方式:)
return ((b >> bitNumber) & 1) != 0;
Run Code Online (Sandbox Code Playgroud)
使用BitArray类并将扩展方法作为OP建议:
public static bool GetBit(this byte b, int bitNumber)
{
System.Collections.BitArray ba = new BitArray(new byte[]{b});
return ba.Get(bitNumber);
}
Run Code Online (Sandbox Code Playgroud)