c# - 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。
我是愚蠢还是这似乎是错误的行为?
解决方案
我确实很笨。正如@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 |
希望这会帮助将来同样愚蠢的人!
推荐阅读
- python - Python:将文本文件拆分为多个工作会话
- java - Oracle AQ / Oracle JMS 的最新 Javadoc
- rest - Camunda REST - 如何获得流表达的可能性
- pymongo - Pymongo 查询变得非常缓慢
- javascript - useRef([]) 与动态创建的元素
- aws-elasticsearch - 如何在 Zeebe 操作中使用 aws elastic-search
- python - 双引号变量中的单引号
- javascript - 为 Web 构建的单页应用程序能否用于使用 react.js 构建 PWA?
- python - 为什么我得到一个 IndexError: list index out of range
- google-bigquery - BigQuery 作业统计信息不完整或作业完成后待处理任务的原因