tags:

views:

853

answers:

3

I'm reading from a binary stream which is big-endian. The BitConverter class does this automatically. Unfortunately, the floating point conversion I need is not the same as BitConverter.ToSingle(byte[]) so I have my own routine from a co-worker. But the input byte[] needs to be in little-endian. Does anyone have a fast way to convert endianness of a byte[] array. Sure, I could swap each byte but there has got to be a trick. Thanks.

A: 

What does the routine from your co-worker look like? If it accesses the bytes explicitly, you could change the code (or rather, create a separate method for big-endian data) instead of reversing the bytes.

Jon Skeet
I need to convert the array beforehand in the message object.
initialZero
Jon, doesn't MiscUtil have an EndianBitConverter?
LBushkin
@LBushkin: It does, and that was my first thought - but it sounds like this is a different problem.
Jon Skeet
@initialZero: It's not at all clear what you mean, I'm afraid. If you've got a routine which is expecting little-endian data, why can't you create an alternative version which expects big-endian data?
Jon Skeet
Yes, I just found MiscUtil and am looking at the source. Thanks.
initialZero
@Jon, it should be in little-endian. I was initially just going to use BitConverter.ToSingle(byte[]) to store the value. But the conversion is wrong. So now I need to convert the endianness of the raw message and pass it through these predefined functions for conversions.
initialZero
+1  A: 

Here is a fast method for changing endianess for singles in a byte array:

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++;
    }
  }
}
Guffa
Say my input in hex is 62,4d,00,4e then the output I thought should be 49,62,4e,00 but this could be because I am working in 16bit words. SwapSingles returns 4e,00,4d,62 which is not what I need.
initialZero
@initialZero: A Single is four bytes. So, is it that you don't have bytes or that they don't represent a Single?
Guffa
A: 

I use LINQ:

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

You can also .Skip() and .Take() to your heart's content, or else use an index in the BitConverter methods.

Pat
Note, `Array.Reverse()` is an old way to do it.
Pat