从字节获取特定位

kei*_*en7 89 c#

我有一个字节,特别是来自字节数组的一个字节,它通过从另一个设备发送的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)

现在你知道它是如何完成的,在低层发生了什么,以及它为什么会起作用.

  • 由于缺少大括号(运算符优先级),这段代码不能编译,它必须是`var bit =(b&(1 << bitNumber-1))!= 0`; (8认同)

Ben*_*igt 51

虽然阅读和理解Josh的答案是好的,但是你可能会更乐意使用Microsoft为此目的提供的类:System.Collections.BitArray 它可用于所有版本的.NET Framework.

  • 这太棒了,但我相信 Josh 的解决方案更快、更有效。 (2认同)

Jos*_*osh 36

这个

public static bool GetBit(this byte b, int bitNumber) {
   return (b & (1 << bitNumber)) != 0;
}
Run Code Online (Sandbox Code Playgroud)

应该这样做,我想.


Asi*_*mez 18

这比 0.1 毫秒更快。

return (b >> bitNumber) & 1;
Run Code Online (Sandbox Code Playgroud)


Pie*_*rOz 9

这样做的另一种方式:)

return ((b >> bitNumber) & 1) != 0;
Run Code Online (Sandbox Code Playgroud)

  • 嗯...我不明白你的意思。如果字节 b = 1,则位置 0 处的位为 1,由 (b&gt;&gt;0)&amp;1 给出,任何大于或等于 1 的位置处的位为 0,由 (b&gt;&gt;n)&amp;1 给出,其中 n&gt;=1还有 (2认同)

Jay*_*ker 6

使用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)

  • 不,请不要为每个位测试创建并丢弃BitArray. (9认同)
  • 你反击请求并说,不要把它称为字节上的方法,在BitArray上调用它.也许字节变量可以完全消失. (2认同)

Ali*_*tad 5

尝试这个:

return (b & (1 << bitNumber))>0;
Run Code Online (Sandbox Code Playgroud)