I want to learn how the computer represents the double
type in bit, but the &
and |
bit operators can't use double
. And memcpy(&d, &src, 8)
also doesn't seem to work. Any suggestions?
views:
598answers:
7Here:
#include <stdio.h>
int main ()
{
double decker = 1.0;
unsigned char * desmond = (unsigned char *) & decker;
int i;
for (i = 0; i < sizeof (double); i++) {
printf ("%02X ", desmond[i]);
}
printf ("\n");
return 0;
}
You can try it: http://codepad.org/onHnAcnC
A particular bit layout by itself is meaningless. Suppose I have the following: 1101
Maybe I say that is unsigned and it represents the value 13.
Maybe it is signed and that high bit signifies that the value is a negative which means it is now -5.
Consider further that I consider the high two bits to be a base and the low two bits to be an exponent, then I get the value 3.
You see, it isnt the storage, its the interpretation. Read up on how floating point values are represented and interpreted; it will serve you much better than seeing how the bits are packed.
This works for me
#include <stdio.h>
#include <string.h> /* memmove */
int main(void) {
unsigned char dontdothis[sizeof (double)];
double x = 62.42;
printf("%f\n", x);
memmove(&dontdothis, &x, sizeof dontdothis);
/* examine/change the array dontdothis */
dontdothis[sizeof x - 1] ^= 0x80;
/* examine/change the array dontdothis */
memmove(&x, &dontdothis, sizeof dontdothis);
printf("%f\n", x);
return 0;
}
The result is
62.420000
-62.420000
The key is to convert the double
to a long long
(assuming sizeof(double) == sizeof(long long)
) without changing binary representation. This can be achieved by one of the following methods:
- cast:
double a; long long b = *((long long *)&a);
- union:
union { double a ; long long b };
union {
double d;
unsigned char c[sizeof(double)];
} d;
int main(int ac, char **av) {
int i;
char s1[80], s2[80];
d.d = 1.0;
for(i = 0; i < sizeof d; ++i) {
sprintf(s1 + i * 3, " %02x", d.c[i]);
sprintf(s2 + i * 3, " %02x", d.c[sizeof d - 1 - i]);
}
printf("%s\n%s\n", s1, s2);
return 0;
}
$ ./a.out
00 00 00 00 00 00 f0 3f
3f f0 00 00 00 00 00 00
Or you could just read about the IEEE 754 standard, which specifies representation.