views:

132

answers:

3

I'm taking in a float as input, and then outputting its equivalent representation in base 2 scientific notation. This is in IEEE 32 bits with: 31 sign bit, 23-30 exponent (with 127 offset), 0-22 mantissa (with implicit leading 1).

One of the conditions which I'm not exactly sure the meaning of is "Your mantissa should have the implicit leading 1 prepended."

All I've really learned is to break up the float into its decimal and fractional parts, and separately get their binary representations.

Since I'm not sure how to do this... I can't really code it. I'd appreciate any tips or information on some sort of algorithm for doing so, or the code itself. Thanks.

Sample:

Input: -40.1 Output: -1.01000000110011001100110 E101

Input: 13.5 Output: 1.10110000000000000000000 E11

EDIT: 127 offset means excess 127 notation right? My book only has excess 128, but I don't know the difference anyways...

A: 

You can cheat, and just use frexp.

Oli Charlesworth
I can only #include iostream
kevin
@kevin: Is this a homework exercise? If so, please add the "homework" tag to your question...
Oli Charlesworth
If that's cheating, I don't want to know what the right answer is.
Potatoswatter
@Potatoswatter: Well, if the exercise is to understand how floating-point is represented, then having a ready-made function to do it for you could be considered cheating!
Oli Charlesworth
@Oli: The way I see it, understanding the results of frexp requires understanding FP fundamentals… all that's left is the bit layout, which depends on endianness anyway.
Potatoswatter
Why the downvote?
Oli Charlesworth
+2  A: 

So I'm not going to do quite all of the work for you, because this sounds like homework. But I'll get you started and you can fill in the gaps. So there's a handy data type in c++ that's called a union, with it you can have multiple data types take up the same space. This is very useful, if say you want to see the bit representation of a floating point number. The following code will output the binary representation of a floating point number:

#include <iostream>
using namespace std;
union b{
   float flo;
   int integ;
};
int main(){

  b thing;
  thing.flo=-40.1;
  for(int i=31;i>=0;i--){
    if((thing.integ & (1 << i)))
      cout << 1;
    else
      cout << 0;
  }
  cout << endl;
}

All that's left for you to do is extract the mantissa and the exponent. You could run the routine once to generate the mantissa and again to generate the exponent. I'll give a brief explanation of how to do both and things to watch out for.

When generating the mantissa remember that IEEE uses a hidden 1 with a reserved code for zero, so there's always going to be an extra one that isn't in the bit representation. Essentially you'll check the sign bit print - or + depending on it, then 1. then skip to the mantissa and print what follows. Then you'll go back to the 23-30 bits, you want to convert it to an int, to do this multiply each bit by 2^i (23 bit is 0, 24 bit is 1, etc) and then you'll want to subtract the offset from the int. Then using the previously outline method output the binary representation of the exponent, I would consider not outputting until you hit a 1. Hope this helps.

Jacob Schlather
A: 

One of the cleanest ways to do this is with bitmasking. Perhaps a better way is with bitfields. You can define a struct to represent the floating point format:

struct float_layout {
  int mantisa : 23
  int exp : 8
  int sign : 1
};

Then get your float, and cast it to this struct:

float b = input;
float_layout layout = *static_cast<float_layout *>(&b)

This reinterprets the bits of data without changing them. Then you can easily access the parts as numbers. Just remember to add the offset for exp and add the leading 1 for the mantissa.

JoshD
Good in principle, but requires you to know the order that `float`s are stored on your platform.
Oli Charlesworth
I may have misunderstood the standard, but I thought it specified how it is to be stored.
JoshD