存储在内存中的双数的高位在哪里?

时间:2014-03-09 01:02:28

标签: c memory double

你好我有关于双打的问题。我在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位机器上?

3 个答案:

答案 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);`