C#在字节和BitArray中的位排序

时间:2014-08-12 09:54:06

标签: c# byte bit endianness

我试图了解关于字数和位排序的信息。

编辑:正如评论中指出的那样,endianess并不关心我的问题,但我喜欢把它放在这里只是为了完整性。至少没有人反对我的定义"。

到目前为止我学到的东西:如果一个值(也许是一个单词)由多个字节组成(字:2个字节),有两种不同的方法可以将这个值保存在连续的记忆块。我们假设我们的小数值为43210(0xA8CA,1010100011001010)

  • BigEndian(第一个)保存字节,这会对较低地址的值幅度产生较大影响,有点像我们写的普通阿拉伯数字。

    Memory address |  1000  |  1001  
    ---------------|--------|---------
    Bytes          |   A8   |   CA
    
  • LittleEndian(第一个)保存字节,该字节对较低地址的值幅度影响较小

    Memory address |  1000  |  1001  
    ---------------|--------|---------
    Bytes          |   CA   |   A8
    

这是对的吗?

我学到的第二件事是,有两种不同的方法可以在内存中保存一个字节的位(坚持使用43210 BigEndian):

  • 最重要的位(第一个/左边)保存,模拟BigEndian用于字节,这些位对内存中的值幅度影响最大,再次:当我们编写阿拉伯数字时。

    Memory address |  1000                         |  1001  
    Bit values     |128|64 |32 |16 |8  |4  |2  |1  |128|64 |32 |16 |8  |4  |2  |1  |
    --------------------------------------------------------------------------------
    Bits           | 1   0   1   0   1   0   0   0 | 1   1   0   0   1   0   1   0
    
  • 最低有效位(第一个/左侧)反转一个字节内的位顺序,因此首先区分偶数和不均匀数字的位

    Memory address |  1000                         |  1001  
    Bit values     |1  |2  |4  |8  |16 |32 |64 |128|1  |2  |4  |8  |16 |32 |64 |128|
    --------------------------------------------------------------------------------
    Bits           | 0   0   0   1   0   1   0   1 | 0   1   0   1   0   0   1   1   
    

这也是正确的吗?

以下是我的方案和问题:我正在通过网络接收数据。协议(Modbus)规定a)数据传输为BigEndian,当必须返回比特时,以字节为单位,MSB在左边,LSB在右边。我用C#,.Net 4.5进行编程。

在很多场合,我已经使用BitConverter类来检查系统的结束(BitConverter.IsLittleEndian),以便通过我的NetSocket正确传递字值。

    public static byte[] CorrectEndianess(byte[] in_byteArray)
    {
        if (BitConverter.IsLittleEndian)
            return in_byteArray.Reverse().ToArray();
        else return in_byteArray;
    }

当我收到一个包含8位表示8个线圈(或输入)状态的字节时,一切都停止了。根据定义,Modbus协议提供以下(示例):

    Coil No. (example) | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |
    -------------------|---------------------------------------|
    Bits               |MSB                                 LSB|
    Example values     | 0  | 0  | 0  | 0  | 0  | 0  | 0  | 1  |

包含此信息的byte在调试器中显示为具有值" 1",这很好。但是,我需要将每个位作为布尔值。 C#提供了BitArray,一个我可以传递字节的类,它返回bool[],非常适合我的目的。

    BitArray ba = new BitArray(new byte[1] { my_byte_which_is_of_value_1 });

如果我打印BitArrays数组,ba[0]包含值true,其余为false。所以我认为BitArray认为单个字节首先是LSB。这很奇怪,因为它打破了比特的剩余处理,期望(例如)ba[7]true

长话短说,这是我的主要问题:

如何在BitArraybyte中检查假设哪个位排序,所以我总是知道我的LSB和MSB在哪里?

旁注:从右到左符号语言编写的数字是BigEndian吗?

2 个答案:

答案 0 :(得分:0)

您是否尝试在发送数据的主机上使用IPAddress.HostToNetworkOrder,然后在接收端使用IPAddress.NetworkToHostOrder,而不是考虑自己确定远程系统的字节顺序?这样,您就可以使代码与endianneas的效果无关。

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.hosttonetworkorder(v=vs.110).aspx

http://msdn.microsoft.com/en-us/library/system.net.ipaddress.networktohostorder(v=vs.110).aspx

答案 1 :(得分:0)

现在,经过几句评论后,我得到了我正在寻找的答案。如果我一直在仔细观察,我会自己偶然发现它。

正如@Alex Farber所指出的,MSDN声明LSB在BitArray中具有最低的索引。我在这里也找到了这个答案:https://stackoverflow.com/a/9066924/1968308