通过附加两个int的二进制表示来创建double

时间:2015-05-30 19:05:01

标签: c binary double bit-manipulation arc4random

我尝试通过附加两个double的二进制表示来创建int。这就是我现在所拥有的:

int i = arc4random();
*(&i+1) = arc4random();
double d = *(double*)&i;

我希望double指针也会使用&i+1地址中的值,事实确实如此。当我打印i*(&i+1)的二进制表示形式并将它们与d的二进制表示形式进行比较时,d由附加*(&i+1)i组成。那么*(&i+1)首先出现了?!为什么会这样?

编辑:还要看看Juan Catalan和Mark Segal的答案,了解使用工会做正确行事的正确方法。

3 个答案:

答案 0 :(得分:4)

请改用union。你仍然可以生成一个NaN但是不会有内存管理问题。

这是union的全部目的,在几种不同类型之间共享一个内存块。

确保您的架构中sizeof(double)等于sizeof(int)

两次

答案 1 :(得分:2)

您可以使用联合,如下所示:

typedef union {
    double d;
    struct {
        int a;
        int b;
    } integers;
} double_generator;

int main(void) {
    double_generator g;
    g.integers.a = arc4random();
    g.integers.b = arc4random();

    // g.d is now a "randomly generated double"

    return 0;
}

或者"手动",可能不安全,自己完成这项工作:

int main(void) {
    double d;
    *((int *)&d) = arc4random();
    *(((int *)&d) + 1) = arc4random();
    printf("%f", d);
    return 0;
}

在这两种情况下,您只需处理相同的内存,就像它是intdouble一样。这可能会生成每个可能的double值,包括NaNInfinity

但是,此代码假定sizeof(double)(至少)是sizeof(int)的两倍。如果它不是,你必须引入不同的代码来处理它。

答案 2 :(得分:1)

  

当我打印i和*(& i + 1)的二进制表示并进行比较时   它们以d的二进制表示形式,d由附加组成   *(& i + 1)和i。所以*(& i + 1)首先出现?!为什么会这样?

字节的实际排序取决于底层硬件架构的“Endian-ness”。

带有小Endian架构:

1) the lowest address byte contains the least significant 8 bits of the total variable  
2) the highest address byte contains the most significant 8 bits of the total variable.