从字节获取特定位
我有一个字节,特别是从另一个设备发送通过UDP进来的字节数组中的一个字节。 该字节存储设备中8个继电器的开/关状态。
如何获得所述字节中特定位的值? 理想情况下,一个扩展方法看起来最优雅,返回一个布尔将对我最有意义。
public static bool GetBit(this byte b, int bitNumber) { //black magic goes here }
简单。 使用按位“与”(AND)将您的数字与值2 ^ bitNumber进行比较,这可以通过位移进行便宜计算。
//your black magic var bit = (b & (1 << bitNumber-1)) != 0;
编辑:添加更多的细节,因为有很多类似的答案没有解释:
按位AND使用AND连接逐位比较每个数字,以产生一个数字,该数字是该位置的第一位和第二位被设置的位的组合。 下面是一个“半字节”中AND逻辑的逻辑matrix,它显示了按位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 ^ 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类并根据OPbuild立扩展方法表明:
public static bool GetBit(this byte b, int bitNumber) { System.Collections.BitArray ba = new BitArray(new byte[]{b}); return ba.Get(bitNumber); }
尝试这个:
return (b & (1 << bitNumber))>0;
该方法是使用另一个字节和一个按位“与”来屏蔽目标位。
我在这里使用惯例,其中“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; } }
这个网站有多个如何从C#中的一个字节获得一些实现。 对此也有相当好的解释。 http://bytes.com/topic/c-sharp/answers/505085-reading-bits-byte-file
尝试下面的代码。 与其他post的不同之处在于,您可以使用掩码( 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
这工作比0.1毫秒快。
return (b >> bitNumber) & 1;