0

Background

First of all, I have some hexadecimal data... 0x3AD3FFD6. I have chosen to represent this data as an array of bytes as follows:

byte[] numBytes = { 0x3A, 0xD3, 0xFF, 0xD6 };

I attempt to convert this array of bytes into its single-precision floating point value by executing the following code:

float floatNumber = 0;
floatNumber = BitConverter.ToSingle(numBytes, 0);

I have calculated this online using this IEEE 754 Converter and got the following result:

0.0016174268

enter image description here

I would expect the output of the C# code to produce the same thing, but instead I am getting something like...

-1.406E+14

Question

Can anybody explain what is going on here?

Snoop
  • 1,046
  • 1
  • 13
  • 33
  • 3
    Reverse the order of the bytes and compare the result. Then see http://stackoverflow.com/questions/2945174/floating-point-endianness (and related) - BitConverter uses a specific endianess. – user2864740 Apr 25 '16 at 16:36
  • 1
    @user2864740 not a specific, but that one that the actual computer uses. It behaves differently on different platforms. – adjan Apr 25 '16 at 16:41
  • Try this : floatNumber = BitConverter.ToSingle(numBytes.Reverse().ToArray(), 0); – jdweng Apr 25 '16 at 16:53
  • @jdweng thanks, will do. – Snoop Apr 25 '16 at 16:55

2 Answers2

3

The bytes are in the wrong order. BitConverter uses the endianness of the underlying system (computer architecture), make sure to use the right endianness always.

adjan
  • 13,371
  • 2
  • 31
  • 48
0

Quick Answer: You've got the order of the bytes in your numBytes array backwards.

Since you're programming in C# I assume you are running on an Intel processor and Intel processors are little endian; that is, they store (and expect) the least significant bytes first. In your numBytes array you are putting the most significant byte first.

BitConverter doesn't so much convert byte array data as interpret it as another base data type. Think of physical memory holding a byte array:

b0 | b1 | b2 | b3.

To interpret that byte array as a single precision float, one must know the endian of the machine, i.e. if the LSByte is stored first or last. It may seem natural that the LSByte comes last because many of us read that way, but for little endian (Intel) processors, that's incorrect.

VictorEE
  • 71
  • 5
  • I was just wondering, do you have a reference for what the array has anything to do with the processor? It's just that... .NET is at such a high level above anything going on at the CPU, so this idea is rather difficult to understand. Thank you. – Snoop Apr 27 '16 at 14:02
  • Two pages where BitConverter's operation is spelled out pretty clearly are https://msdn.microsoft.com/en-us/library/system.bitconverter.tosingle%28v=vs.110%29.aspx and https://msdn.microsoft.com/en-us/library/system.bitconverter%28v=vs.110%29.aspx. The latter particularly has some good info after the examples. I made some edits to my answer that may help too. – VictorEE Apr 27 '16 at 19:44