我尝试通过附加两个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的答案,了解使用工会做正确行事的正确方法。
答案 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;
}
在这两种情况下,您只需处理相同的内存,就像它是int
或double
一样。这可能会生成每个可能的double
值,包括NaN
或Infinity
。
但是,此代码假定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.