Thread: binary representation of a float

1. binary representation of a float

I was curious to see exactly how a float (and a double) is stored in memory so I wrote this little program to let me see the actual bits for the numbers 0-9 stored as floats:
Code:
```#include <iostream>
#include <string>
using namespace std;

int main( int argc, char* argv[] ) {
float num; // = atof( argv[1] );
int *ip = (int*)&num;
int size, digit;
string ch;
string binstr;
size = sizeof(num);
cout << "sizeof int = " << sizeof(size) << endl;
cout << "sizeof float = " << sizeof(num) << endl;

for( int k = 0; k < 10; ++k ) {
num = k;
for( int j = 0; j < size; ++j ) {
for( int i = 0; i < 8; ++i ) {
digit = 1 & (*ip);
ch = string( 1, (char)(48 + digit) );
binstr.insert( 0, ch );
*ip >>= 1;
}
binstr.insert( 0, " ");
}
cout << binstr << endl;
binstr = "";
}

return 0;
}```
I thought I understood that a 32-bit float is stored as an 8-bit exponent and 24-bit significand, so (assuming the first byte would be the exponent, 0, and the next 3 bytes would be the significand) I was expecting as output:
Code:
```sizeof int = 4
sizeof float = 4
00000000 00000000 00000000 00000000
00000000 00000001 00000000 00000000
00000000 00000010 00000000 00000000
00000000 00000011 00000000 00000000
00000000 00000100 00000000 00000000
00000000 00000101 00000000 00000000
00000000 00000110 00000000 00000000
00000000 00000111 00000000 00000000
00000000 00001000 00000000 00000000
00000000 00001001 00000000 00000000```
but instead, this is the surprising output:
Code:
```sizeof int = 4
sizeof float = 4
00000000 00000000 00000000 00000000
00111111 10000000 00000000 00000000
01000000 00000000 00000000 00000000
01000000 01000000 00000000 00000000
01000000 10000000 00000000 00000000
01000000 10100000 00000000 00000000
01000000 11000000 00000000 00000000
01000000 11100000 00000000 00000000
01000001 00000000 00000000 00000000
01000001 00010000 00000000 00000000```
Can you explain this?

(My code may not be the most elegant way to do this, but I don't see anything actually wrong in it, do you?)

2. > I thought I understood that a 32-bit float is stored as an 8-bit exponent and 24-bit significand
1 sign bit
8 bit biased exponent
23 bit mantissa with an implied 1
http://en.wikipedia.org/wiki/Single_precision

3. Ok, so aside from the correction of the misunderstood format of floating point in itself, there are some other things to consider:
1. There is an implicit 1 at the beginning of all non-zero values, so when you have 1.0 (for example), it is actually stored with all zeros in the mantissa, because the single 1 that is at the beginning is implied by the floating point format itself.
2. The stored number is ALWAYS normalized, that is the actual bits of the mantissa is always as far left as it can be - or put another way, the exponent is always the smallest it can be.
3. The exponent is stored as a biased number - it is 128+actual value. So 1.0 is stored as exponent of 127 and a mantissa of all zeros, for example.

--
Mats

4. Thanks. I had looked at a couple of articles in Wikipedia but didn't find that one.

That's quite a system. I'd love to hear Bob Newhart explain it.

5. Originally Posted by matsp
3. The exponent is stored as a biased number - it is 128+actual value. So 1.0 is stored as exponent of 127 and a mantissa of all zeros, for example.
127, I think? Although, the second part is correct - 1.0 is stored as an exponent of 127 and a mantissa of all zeros: 127 - [bias of] 127 = 0, so: 1.0 * 2^0 = 1.0

6. Yes, the bias is 127 as explained in the Wikipedia article. All of the encodings in my output example bear that out.