你好我有关于双打的问题。我在IA32机器上,想看看在内存中如何表示double。下面我有一个程序。
int main(int argc, char *argv[])
{
double d = 0.333333333333333314829616256247390992939472198486328125; //in hex: 3FD5 5555 5555 5555
printf("%x\n", d); //prints 55555555
return 0;
}
由于某种原因,这只打印后4个字节,即5555555.我的问题是高位(3FD5 5555)存储在哪里?它在地址(& d + 4)?或(& d - 4)或内存中定义的其他地方?由于double有8个字节,它如何存储在32位机器上?
答案 0 :(得分:1)
在今天的大多数机器中,double
有8个字节,尝试使用long long
(至少64位),如下所示:
printf("%llx\n", *(long long*)(&d));
答案 1 :(得分:1)
我不会以任何方式说出以下内容是“正确的”,但它Works Here (TM) - 或者实际上对于ideone使用的任何编译器/机器(为了继续这个答案,我将假设它是一个现代的x86目标) - 可用于检查double值的各个字节/位。
#include <stdio.h>
int main(void) {
double d = (double)1/3;
unsigned char *x = (unsigned char *)&d;
printf("chars: %2x%2x %2x%2x %2x%2x %2x%2x\n",
x[0], x[1], x[2], x[3], x[4], x[5], x[6], x[7]);
// as per Yu Hao's answer
long long dd = *(long long*)&d;
printf("lld : %8llx\n", dd);
return 0;
}
结果:
chars: 5555 5555 5555 d53f // raw view doesn't account for LE/reversal
lld : 3fd5555555555555 // this is the "correct" value
由于little-endian性质(在每对字节内)的整数在内存中的编码方式(并且MSB影响幅度最大),两个输出中的值不同,而个人字符是“按记忆顺序”。
以1234.5678
作为输入,结果为:
chars: adfa 5c6d 454a 9340
lld : 40934a456d5cfaad
通过一些解读,可以看到相关性:
chars: AAaa BBbb CCcc DDdd
lld : ddDDccCCbbBBaaAA
答案 2 :(得分:1)
查看double
的十六进制特性的便携方法。 "%a"
以十六进制有效数和十进制指数表示法打印double
。
printf("%a\n", d);
一种不完全但合理的便携式方法
即使long long
超过8个字节,这也适用
(如今,与长度不同的长长度并不常见。)
#include <inttypes.h>
...
printf("%016" PRIX64 "\n", *(uint64_t *) &d);`