1

I am trying to read a floating point number stored as a specific binary format in a char array. The format is as follows, where each letter represents a binary digit:

SEEEEEEE MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM MMMMMMMM

The format is more clearly explained in this website. Basically, the exponent is in Excess-64 notation and the mantissa is normalized to values <1 and >1/16. To get the true value of the number the mantissa is multipled by 16 to the power of the true value of the exponent.

Basicly, what I've done so far is to extract the sign and the exponent values, but I'm having trouble extracting the mantissa. The implementation I'm trying is quite brute force and is probably far from ideal in terms of code but it seemed to me as the simplest. It basicly is:

unsigned long a = 0;
for(int i = 0; i < 7; i++)
    a += static_cast<unsigned long>(m_bufRecord[index+1+i])<<((6-i)*8);

It takes every 8-bit byte size stored in the char array and shifts it left according to its index in the array. So if the array I have is as follows:

{0x3f, 0x28, 0xf5, 0xc2, 0x8f, 0x5c, 0x28, 0xf6}

I'm expecting a to take the value:

0x28f5c28f5c28f6

However, with the above implementation a takes the value:

0x27f4c18f5c27f6

Later, I convert the long integer to a floating number using the following code:

double m = a;

m = m*(pow(16, e-14));
m = (s==1)?-m:m;

What is going wrong here? Also, I'd love to know how a conversion like this would be implemented ideally?

8
  • 2
    This is like the tenth question in the last two days about the exact same thing. Is it some kind of homework deadline? Does your prof know that you're asking for an answer on SO about this? Commented Feb 10, 2013 at 15:22
  • Well, unfortunately, I haven't seen the previous questions, though I did a search if anything similar was asked before. The context of this, if you must know, is about reading a GDSII format file (a file format to store IC layouts primarily.) More information here: (boolean.klaasholwerda.nl/interface/bnf/gdsformat.html) Also, no professors are involved whatsoever. Commented Feb 10, 2013 at 15:25
  • Fair enough, and apologies for the insinuation. Commented Feb 10, 2013 at 15:30
  • Does a long actually have enough size for 56 bits? In any event you could write the binary representation of an IEE754 double directly without the intermediate step. Commented Feb 10, 2013 at 15:33
  • Is the format actually matching a 64-bit? Isn't the exponent more than 8 bits in a double? Commented Feb 10, 2013 at 15:38

1 Answer 1

1

I haven't tried running your code, but I suspect the reason you get this:

0x27f4c18f5c27f6

instead of

0x28f5c28f5c28f6

is because your have a "negative number" in the cell previous to it. Are your 8-bit byte array a signed or unsigned value? I expect it will work better if you make it unsigned. [Or move your cast so that it's before the shift operations].

Sign up to request clarification or add additional context in comments.

5 Comments

My byte array is a char* so it is signed, but I think I'm doing the casting before the the shift operation. Is the above code not doing that?
I would print the intermediate values before "adding" [I personally would use | to or in the the values, as that saves any unwanted "borrowing" if adding negative values, etc].
This certainly seems to be the problem, static_cast<unsigned long>(0xf3) (0xf3 is actually a value stored in a char* array) results in 0xfffffffffffffff3 which is certainly not what I want. Correcting the expression to static_cast<unsigned long>(0xf3)&0xff seems to solve the problem but what I don't understand is if this is intended behavior?
I think what happens is that it's extended to long first, then converted to unsigned, which is the opposite of what you need. I have had similar problems in the past, and had to either do double casts or use unsigned in the first place [which probably would solve the problem in your case too].
Makes sense. Using static_cast<unsigned>() doesn't work for my case due to the size of the default int. I'll either have to use a double cast or the static_cast<unsigned long>()&0xff. I think I'll favor the double cast due to its better readability.

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.