3

Please check this code

float f = BitConverter.ToSingle(new byte[] { 0xBF, 0x04, 0x8E, 0xFF }, 0);
byte[] b = BitConverter.GetBytes(f);

this yeilds a strange result. b will be { 0xBF, 0x04, 0xCE, 0xFF }

I guess it is because the value of f is NaN. the reason I'm asking this question is because I use Marsal to convert a stream of bytes into a struct that contains a float, the I swap endianity

The thing is when I get to the field is already messed up (like the above example)

any ideas?

Thanks!

9
  • 1
    Change the endianity before converting it to a float Commented Nov 28, 2013 at 8:28
  • I can't.I'm converting a byte[] to struct which it's inner structure is not known to me at that stage. Commented Nov 28, 2013 at 8:30
  • 1
    @harold if you use BitConverter in both directions, endianness isn't a concern - indeed, that would be the issue if the bytes were reversed, not if they are just mutated Commented Nov 28, 2013 at 8:31
  • 1
    @MarcGravell it is a concern this time, because the original input (ie { 0xBF, 0x04, 0x8E, 0xFF }) is the wrong way around. That makes a NaN, and then things start going south. Commented Nov 28, 2013 at 8:34
  • 1
    @TheDude please clarify, is this value supposed to be a NaN? Or something like -0.51780695 Commented Nov 28, 2013 at 9:20

2 Answers 2

2

Since your problem appears to an endian one, I'm wondering if checking for NaN and reversing the order and setting a boolean to reverse it back if necessary, would help:

byte[] input = { 0xBF, 0x04, 0x8E, 0xFF };
bool reversed = false;
float f = BitConverter.ToSingle(input, 0);

if (float.IsNaN(f))
{
    reversed = true;
    f = BitConverter.ToSingle(input.Reverse().ToArray(), 0);
}

byte[] b = BitConverter.GetBytes(f);

if (reversed)
    b = b.Reverse().ToArray();
Sign up to request clarification or add additional context in comments.

5 Comments

f == float.NaN will always be false. Change it to float.IsNaN(f).
@AgentFire viva le Resharper
@RoyiNamir eh no, without any tools, I just checked the code out.
@AgentFire , well , My resharper warned me about it.
@AgentFire The best.(IMO).
0

This works:

double f = BitConverter.ToDouble(new byte[] { 0, 0, 0, 0, 0xBF, 0x04, 0x8E, 0xFF }, 0);
byte[] b = BitConverter.GetBytes(f);

This one also does:

int f = BitConverter.ToInt32(new byte[] { 0xBF, 0x04, 0x8E, 0xFF }, 0);
byte[] b = BitConverter.GetBytes(f);

I believe the reason is in the single floating-point storage. The third byte ({ 0xBF, 0x04, [0x8E to 0xBE] , 0xFF } is being +4'd for some reason while converted.

The good containter for 4 bytes is Int32 and I advise you to use it.

3 Comments

That double represents a completely different number and is irrelevant. This is not a decimal precision issue, because the number is already in binary format. The problem here is that the bytes result in NaN. If OP just wanted to have a container for 4 bytes, why not just use a byte[]?
@Rik at least because byte[] as well as any other array is a reference typed object. And the double is still a container as well.
This should be the selected answer, because it not only explains clearly what caused the byte in question to be altered, but it also shows two good solutions when 4-byte data chunks must be passed through BitConverter twice in opposite directions, but they cannot be guaranteed to be valid single floats. There are a number of situations in which this arises. This was very helpful to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.