【问题标题】:What byte order when BitConverter.IsLittleEndian = falseBitConverter.IsLittleEndian = false 时的字节顺序
【发布时间】:2014-09-25 09:40:39
【问题描述】:

我以字节等效格式存储数字,使用尽可能少的字节数。在 65535 到 16777215 的范围内,BitConverter 给了我一个 4 字节的数组,但我只想存储 3 个字节。

对于下面的代码,我的数组是[0]254、[1]255、[2]255、[3]0,所以我可以去掉字节[3]。这是在Core i7 proc上。在我的生产代码中,在数组复制之前,我正在检查 BitConverter.IsLittleEndian 以确定我可以截断最后一个字节。

int i = 16777214;
byte[] bytesTemp = BitConverter.GetBytes(i);

byte[] value = null;
if (BitConverter.IsLittleEndian) 
    Array.Copy(bytesTemp, 0, value, 0, 3); 

我的问题是 - 我是否需要关注系统的字节序,或者 CLR 是否只使用这种 LittleEndian 格式?我没有 BigEndian 系统(甚至不知道如何获得)来测试我的字节数组是否以相反的顺序出现。

【问题讨论】:

  • 这取决于计算机架构,大多数架构都是LittleEndian。但是,.Net 代码可以在 BigEndian 架构上运行 - .NET Micro Framework 可以在 big-endian 上运行。 4.1 版增加了对 big-endian 的支持。
  • 我希望你这样做不是为了节省空间。
  • 如果空间是您关心的问题 - 您可以考虑像“varint”这样的东西; 0-127 需要 1 个字节; 128-16,383 为 2 个字节; 16,384 到 2,097,151 的 3 个字节; 2,097,152 到 268,435,455 的 4 个字节;和 268,435,456 到 4,294,967,295 的 5 个字节(假设无符号等) - 并定义了字节顺序(/cc @Rawling)(实际上,5 个字节带你一直到 34,359,738,367 - 如果你真的需要它)
  • @MarcGravell - 我能找到 varint 的唯一参考是这个 [link]pastebin.com/Qk7LXESQ?
  • @winnt93 这是来自“协议缓冲区”的编码细节;这里:developers.google.com/protocol-buffers/docs/encoding#varints - 基本上,它使用 7 位数据,第 8 位作为继续标志; example reader; example writer

标签: c# bitconverter


【解决方案1】:

是的,根据documentation,您需要关注。他们有一个例子,如果架构不是所需的字节序,他们会反转字节。

至于从哪里获得 BigEndian 系统,我认为基于 ARM 的处理器是 big-endian,尽管我没有对此进行测试。因此,例如,如果您在 Win RT 设备或手机上运行,​​您可能会得到不同的行为。

【讨论】:

  • Itaniums 也是 big-endian,虽然 IIRC 如果需要,它们可以运行单个进程 litle-endian,同样 IIRC:在运行 .NET 时,它们总是以 little-endian 结束
  • 这基本上回答了我的问题 - 是的,我需要担心,我错过了 MSDN 文档中的那一点(所以我现在有一个检查和一个 array.reverse 需要时)。但是,@MarcGravell 提到了 varint,这也很有帮助。
【解决方案2】:

这完全取决于您对数据的处理方式。如果您要将其写入磁盘以实现便携式持久性,那么是的......我可能会关心字节顺序。如果您只是打算稍后在同一进程中(或在同一台机器上)使用它来重新创建int,那么它可能并不重要。

但是,当我确实需要担心字节顺序时,我通常无法通过BitConverter 实现这一点根本 - 就个人而言,我很想使用字节掩码和移位;那么你甚至不需要知道字节序——它在任何系统上都一样。它还避免了BitConverter返回字节数组而不是接受数组和偏移量的恼人的糟糕设计决策。

例如:

byte[] buffer = ...

// write little-endian
buffer[offset++] = (byte)(i & 0xFF);
buffer[offset++] = (byte)((i >> 8) & 0xFF);
buffer[offset++] = (byte)((i >> 16) & 0xFF);
buffer[offset++] = (byte)((i >> 24) & 0xFF);

【讨论】:

  • 这里可能有点跑题了,但是你为什么说创建和返回数组而不是接受它是一个错误的决定?
  • @TheodorosChatzigiannakis 不必要的数组分配;在大多数需要值字节的情况下,您已经在使用本地缓冲区 - 能够使用会很好:BitConverter.GetBytes(i, buffer, offset);
  • It entirely depends on what you are doing with the data - 好吧,他正在尝试删除多余的 0 字节,所以我很确定他应该关心字节序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2010-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-26
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多