首页 > 解决方案 > BitConverter 是否错误地处理小端?

问题描述

我目前正在用 C#/.NET 编写一些东西,其中涉及在网络数据包中发送无符号 16 位整数。字节的顺序需要大端。

在位级别,我对“大端”的理解是最重要的位在最后,而小端则相反。

在字节级别,我的理解是相同的——如果我将一个 16 位整数转换为组成它的两个 8 位整数,并且架构是小端,那么我希望最高有效字节位于开始。

但是,BitConverter 似乎将具有最小值的字节放在数组的末尾,而不是具有最低有效值的字节,例如

    ushort number = 4;
    var bytes = BitConverter.GetBytes(number);
    Debug.Assert(bytes[BitConverter.IsLittleEndian ? 0 : 1] == 0);

为清楚起见,如果我的理解是正确的,那么在 little endian machine 上,我希望上述内容会返回0x00, 0x04,而在 big endian machine 上0x04, 0x00。但是,在我运行 .NET 5 的小端 Windows x86 工作站上,它返回0x04, 0x00

甚至有记录表明他们已经考虑了字节序。来自:https ://docs.microsoft.com/en-us/dotnet/api/system.bitconverter.getbytes?view=net-5.0

GetBytes 方法返回的数组中的字节顺序取决于计算机体系结构是 little-endian 还是 big-endian。

我是愚蠢还是这似乎是错误的行为?

标签: c#.netbitconverter

解决方案


我确实很笨。正如@mjwills 所指出的,微软的文档解释了(https://docs.microsoft.com/en-us/dotnet/api/system.bitconverter.islittleendian?view=net-5.0#remarks):

“Big-endian”意味着最高有效字节位于单词的左端。“Little-endian”意味着最高有效字节位于单词的右端。

维基百科有一个稍微好一点的解释:

大端系统将字的最高有效字节存储在最小的内存地址,而最低有效字节存储在最大的内存地址。相反,little-endian 系统将最低有效字节存储在最小地址。

因此,如果您想象内存地址,则将值为 4 的 16 位整数转换为:

地址 0x00 0x01
小端序 0x04 0x00
大端序 0x00 0x04

希望这会帮助将来同样愚蠢的人!


推荐阅读