Originally Posted by
Vladimir Pewton
Wow thanks for you time! I think my understanding of this topic is way better now. I wanted to see why since I multiplied it by 0.01 instead of dividing, and I got the right answer. So I changed the if statement to have g * 0.01 instead, and I got that it failed about 10% of the time. Thank you for answering my question and showing me this small program.
The difference between multiplying by 0.01 instead of dividing by 100 is that 100 can be represented exactly whereas 0.01 can't (since it's stored in binary). So you get different results.
Here's a program that displays the representation of a float. It prints the sign bit, the eight exponent bits (and the decimal value of the exponent in parentheses), and the 24 significand bits (where the leading bit before the binary point is the implied bit, meaning it is not actually stored).
Code:
#include <stdio.h>
typedef unsigned char byte;
#define putbit(b, m) putchar(b & m ? '1' : '0')
void print_float_bits(float f) {
byte *p = (byte*)&f; // pointer to bytes
byte m = 0x80; // bit mask
unsigned exponent = 0;
// sign bit
putbit(p[3], m);
putchar(' ');
// exponent
for (m >>= 1; m; m >>= 1) {
exponent = (exponent << 1) | !!(p[3] & m);
putbit(p[3], m);
}
m = 0x80;
exponent = (exponent << 1) | !!(p[2] & m);
putbit(p[2], m);
printf(" (%d)", (int)exponent - 127);
// significand
printf(" %c.", exponent != 0 && exponent != 255 ? '1' : '0');
for (m >>= 1; m; m >>= 1) putbit(p[2], m);
for (m = 0x80; m; m >>= 1) putbit(p[1], m);
for (m = 0x80; m; m >>= 1) putbit(p[0], m);
putchar('\n');
}
int main() {
float f;
while (printf(">>> "), scanf("%f", &f) == 1) {
printf("%e\n", f);
print_float_bits(f);
}
putchar('\n');
return 0;
}
Example run:
Code:
>>> 100
1.000000e+02
0 10000101 (6) 1.10010000000000000000000
>>> .01
1.000000e-02
0 01111000 (-7) 1.01000111101011100001010