1

I am using c# and writing a program to send numbers over UDP. I am on the Windows 10 64bit platform and I am using BitConverter in order to get the bytes from integers, doubles, etc..

As an example:

If I use:

Byte[] data = BitConverter.GetBytes((int)1);

I get, 01000000 in HEX, which would be little endian as expected.

If I use:

Byte[] data = BitConverter.GetBytes((double)1);

I get, 000000000000f03f in HEX, which looks like a big endian number but I am just not so sure.

My guess is I don't have a good understanding of endianess or of the double format. I suppose it is also possible that Windows stores doubles different from ints?

Spiradev
  • 13
  • 3

3 Answers3

1

Binary representation of double is different from that of integer. It follows the ieee standard for storing floating point values. Use the ieee standard and get the binary representation of 1 and then check fir endianness.

DroidSK
  • 71
  • 6
1

An interesting note. As you might already know, C# doesn't define the endiannes and it depends on the cpu architecture, if you are writing cross platform/architecture applications you can check with the method call BitConverter.IsLittleEndian

Indicates the byte order ("endianness") in which data is stored in this computer architecture.

Remarks

Different computer architectures store data using different byte orders. "Big-endian" means the most significant byte is on the left end of a word. "Little-endian" means the most significant byte is on the right end of a word.

Note

You can convert from network byte order to the byte order of the host computer without retrieving the value of the BitConverter.IsLittleEndian field by passing a 16-bit, 32-bit, or 64 bit integer to the IPAddress.HostToNetworkOrder method.

If you need different endiannes, you can convert easily enough with Array.Reverse.

byte[] bytes = BitConverter.GetBytes(num);
Array.Reverse(bytes, 0, bytes.Length);

or bitwise switch with types like int and long, you could take it a step further with unsafe and pointers for other types

public uint SwapBytes(uint x)
{
    x = (x >> 16) | (x << 16);
    return ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
}

public ulong SwapBytes(ulong x)
{
    x = (x >> 32) | (x << 32);
    x = ((x & 0xFFFF0000FFFF0000) >> 16) | ((x & 0x0000FFFF0000FFFF) << 16);
    return ((x & 0xFF00FF00FF00FF00) >> 8) | ((x & 0x00FF00FF00FF00FF) << 8);
}
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
0

Certainly little-endian.

Remember that IEEE floating-point is a bitfield, with sign having higher significance than exponent, which in turn has higher significance than mantissa.

Your integer example has only one field, and its low bits are set.

Your double example has all zero bits in the mantissa field, and the more significant field of exponent bits is non-zero. (Both of these are affected by the biasing used by IEEE-754)

The significant bits are at the higher memory addresses, just like with the little-endian integer.

For reference, IEEE-754 for 1.0 is { sign: 0, exponent: 0x3ff, mantissa: 0x0000000000000 }

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720