我想学习计算机如何用二进制表示双精度类型,但是位运算符&
和|
不能用于double
。而memcpy(&d, &src, 8)
也似乎不起作用。有什么建议吗?
我想学习计算机如何用二进制表示双精度类型,但是位运算符&
和|
不能用于double
。而memcpy(&d, &src, 8)
也似乎不起作用。有什么建议吗?
在这里:
#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;
}
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
一个特定的位布局本身是没有意义的。假设我有以下内容:1101
也许我说它是无符号的,表示值为13。
也许它是带符号的,高位表示该值为负数,这意味着现在是-5。
进一步考虑,我认为高两位是基数,低两位是指数,那么我得到的值是3。
你看,它不是存储,而是解释。阅读有关浮点值如何表示和解释的文章,这比查看位的打包方式更有用。
这对我有效
#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;
}
结果是
62.420000
-62.420000
关键在于将 double
转换为 long long
(假设 sizeof(double) == sizeof(long long)
),而不改变二进制表示。以下是实现此任务的两种方法:
double a; long long b = *((long long *)&a);
union { double a ; long long b };