在C#中,将字节数组从大端序转换为小端序的快速方法是什么?

5

我正在读取一个大端字节流。BitConverter类可以自动处理这个问题。不幸的是,我需要的浮点数转换并不同于BitConverter.ToSingle(byte[]),因此我从我的同事那里得到了一种自己的方法。但输入的byte[]数组需要是小端的。有人知道一种快速的方法来转换byte[]数组的字节序吗?当然,我可以交换每个字节,但应该有更简单的方法。谢谢。

3个回答

4

以下是一种快速更改字节数组中单精度浮点数大小端的方法:

public static unsafe void SwapSingles(byte[] data) {
  int cnt = data.Length / 4;
  fixed (byte* d = data) {
    byte* p = d;
    while (cnt-- > 0) {
      byte a = *p;
      p++;
      byte b = *p;
      *p = *(p + 1);
      p++;
      *p = b;
      p++;
      *(p - 3) = *p;
      *p = a;
      p++;
    }
  }
}

假设我的十六进制输入是62,4d,00,4e,那么我认为输出应该是49,62,4e,00,但这可能是因为我在16位字中工作。SwapSingles返回的是4e,00,4d,62,这不是我需要的。 - initialZero
@initialZero: Single 是四个字节。那么,是你没有字节,还是它们不代表 Single? - Guffa

3

我使用LINQ:

var bytes = new byte[] {0, 0, 0, 1};
var littleEndianBytes = bytes.Reverse().ToArray();
Single x = BitConverter.ToSingle(littleEndianBytes, 0);

您可以尽情使用 .Skip().Take() 方法,或者在 BitConverter 方法中使用索引。


1
注意,Array.Reverse() 是一种旧的方法。 - Pat
快速实现?也许是。运行时快吗?可能不是。 - ulrichb
@Pat Array.Reverse修改原始数组,而.Reverse().ToArray()创建一个新数组。差别很大。这与旧的或新的方法无关。 - juFo
@juFo 我的意思是,如果你使用的是早于LINQ的.NET版本,因此需要使用.Reverse().ToArray()。但是澄清这个区别对大家来说是个好主意。 - Pat

0

你的同事编写的程序是什么样子的?如果它显式地访问字节,你可以改变代码(或者创建一个专门处理大端数据的方法),而不是翻转字节。


我需要在消息对象中事先转换数组。 - initialZero
Jon,MiscUtil没有EndianBitConverter吗? - LBushkin
1
@LBushkin:确实如此,这是我的第一个想法 - 但听起来这是一个不同的问题。 - Jon Skeet
@initialZero:很抱歉,我不太明白你的意思。如果你有一个期望小端数据的例程,为什么不能创建一个期望大端数据的替代版本呢? - Jon Skeet
是的,我刚发现了 MiscUtil 并正在查看源代码。谢谢。 - initialZero
@Jon,应该使用小端序。我最初只是想使用BitConverter.ToSingle(byte[])来存储值。但是转换是错误的。所以现在我需要转换原始消息的字节序,并通过这些预定义的函数进行转换。 - initialZero

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接