由于(通常)一个 double 有 64 位,每个 int 有 32 位,你会认为你可以直接将这些位存储到 double 中,例如:
int32_t i1 = rand();
int32_t i2 = rand();
int64_t x = (((int64_t)i1)<<32) | ((int64_t)i2);
double theDouble;
memcpy(&theDouble, &x, sizeof(theDouble));
......并且这样做“几乎有效”。也就是说,它适用于 i1 和 i2 的许多可能值——但并非适用于所有值。特别是,对于 IEEE754 浮点格式,指数位设置为 0x7ff 的任何值都将被视为指示“NaN”,并且浮点硬件可以(并且确实)将不同的 NaN 等效位模式转换回其首选将 double 作为参数传递时的 NaN 位模式等。
正因为如此,在大多数情况下,将两个 32 位整数填充到双精度中似乎是可行的,但是如果您使用所有可能的输入值对其进行测试,您会发现在某些情况下,这些值在它们停留在双精度中时会意外变异,并且当您再次解码它们时,它们会出现不同的值。
当然,您可以通过仅设置双精度的尾数位来解决此问题,但这只会为每个整数提供 26 位,因此您只能存储 +/- 33,554,432 左右的整数值。也许没关系,具体取决于您的用例。
我的建议是,找到一种不同的方式来做你想做的任何事情。将非浮点数据存储在浮点变量中是自找麻烦,特别是如果您希望您的代码完全可移植。