C# 如何将每一位从一个字节中分离出来?

C# 如何将每一位从一个字节中分离出来?,c#,C#,我对C#非常陌生(一般来说是C),我从外部源返回一个字节值,表示IO设备端口上8个输入管脚的状态,因此我得到一个0-255的值,表示端口上存在的二进制模式 我如何去掉单个位并将它们设置为布尔变量,这样做: if (inputBuffer[1] == 1) { IO.Input0 = true; IO.Input1 = false; IO.Input2 = false; IO.Input3 = false; IO.Input4 = false;

我对C#非常陌生(一般来说是C),我从外部源返回一个字节值,表示IO设备端口上8个输入管脚的状态,因此我得到一个0-255的值,表示端口上存在的二进制模式

我如何去掉单个位并将它们设置为布尔变量,这样做:

if (inputBuffer[1] == 1)
{
     IO.Input0 = true;
     IO.Input1 = false;
     IO.Input2 = false;
     IO.Input3 = false;
     IO.Input4 = false;
     IO.Input5 = false;
     IO.Input6 = false;
     IO.Input7 = false;
}    
我可能对我试图实现的目标做了过度的阐述,但我认为这是最好的例子,虽然非常不切实际,但如何才能更好地实现这一点,基于字节值0-255设置变量。

使用位and(
&
)。假设
Input0
表示最低有效位:

IO.Input0 = (inputBuffer & 0x01) == 0x01;
IO.Input1 = (inputBuffer & 0x02) == 0x02;
IO.Input2 = (inputBuffer & 0x04) == 0x04;
IO.Input3 = (inputBuffer & 0x08) == 0x08;
IO.Input4 = (inputBuffer & 0x10) == 0x10;
IO.Input5 = (inputBuffer & 0x20) == 0x20;
IO.Input6 = (inputBuffer & 0x40) == 0x40;
IO.Input7 = (inputBuffer & 0x80) == 0x80;

您还可以实现如下扩展方法:

public static bool IsBitSet(this byte b, int bit)
{
    if(bit < 0 || bit > 7)
        throw new ArgumentOutOfRangeException("bit must be between 0 and 7");

    byte bitToCheck = (byte)(0x01 << bit);

    return (b & bitToCheck) == bitToCheck;
}

使用位掩码和
&
-运算符来解决此问题

byte b = 100;

if(b&1 == 1) { } //bit 1 is set
if(b&2 == 2) { } //bit 2 is set
if(b&4 == 4) { } //bit 3 is set
...

我认为自编的课程会有所帮助。类可以包含8位,构造函数接受一个字节。在构造函数中,您可以计算单个位

public class myByte
{
    bool    Input0 = false;
    bool    Input1 = false;
    bool    Input2 = false;
    bool    Input3 = false;
    bool    Input4 = false;
    bool    Input5 = false;
    bool    Input6 = false;
    bool    Input7 = false;        

    public myByte(byte b)
    {
        //written by Ic.
        Input0 = b & 0x01 == 0x01;
        Input1 = b & 0x02 == 0x02;
        Input2 = b & 0x04 == 0x04;
        Input3 = b & 0x08 == 0x08;
        Input4 = b & 0x10 == 0x10;
        Input5 = b & 0x20 == 0x20;
        Input6 = b & 0x40 == 0x40;
        Input7 = b & 0x80 == 0x80;
    }
    ... //getter setter ...
}
你可以这样做

int x= inputBuffer[1];

bit1 = ((x>>7)&1==1);
bit2 = ((x>>6)&1==1);
bit3 = ((x>>5)&1==1);
bit4 = ((x>>4)&1==1);
bit5 = ((x>>3)&1==1);
bit6 = ((x>>2)&1==1);
bit7 = ((x>>1)&1==1);
bit8 = (x&1==1);

要从11101110值中获取第一位,您需要先将bt右移7次,然后使用1进行操作,这将告诉您该值是1还是0,同样的解决方案也适用于其他位。

如果数据以字节形式提供给您,并且每个位都被屏蔽,那么我将保持原样。将它们转换为另一种类型是不必要的,这将是一项没有任何好处的额外工作。要获得正确的位,只需使用位掩码模式

private bool GetMaskedBit(var inputBuffer , int mask)
{
    return ((inputBuffer & mask) != 0);
}

通过这种方式,您可以解析缓冲区和所需的位,这将返回位是否已设置。

您可以使用
BitArray

var bitArray = new BitArray(inputBuffer);
IO.Input1 = bitArray[byteIndex * 8 + 1];

您还可以将其作为布尔值的集合进行迭代,并对整个集合执行逐位操作


显然,它的性能不如这里提供的其他选项(分配成本),但它确实为位计算提供了一个非常简洁的API。

C和C在名称和某些语法上可能看起来很相似,但我不会将它们组合在一起。C#和Java可能比C#和C共享更多。在我看来,C#的名字只是一个聪明的微软营销策略。@DAB是的,因为
ISO/IEC 23270:2006
只是没有完全相同的含义<代码>:)在编辑之前,如果设置了(b&1){}//位1,则您有
,但现在您已经编辑了它,并且它现在是正确的。为什么不直接
返回(inputBuffer&mask)!=0
?它们需要为每个输入转换为单独的布尔变量,因为它简化了其他地方的内容
var bitArray = new BitArray(inputBuffer);
IO.Input1 = bitArray[byteIndex * 8 + 1];
var bitArray = new BitArray(new byte[] { inputBuffer[1] });
IO.Input1 = bitArray[1];