将大整数转换为float

And*_*ger 3 c floating-point integer type-conversion

我试图将一个整数转换为像这样的浮点数(简化):

int64_t x = -((int64_t)1 << 63);
float y = x;
Run Code Online (Sandbox Code Playgroud)

使用64位Windows 7上的MSVC 2013,这可以正常工作,但在Ubuntu 14.04 64位上使用gcc 4.8,我得到x的正值.我禁用了所有优化并查看了gdb中的变量.我甚至尝试直接用gdb进行评估,以找出问题的原因:

(gdb) print (float)(-((int64_t)1 << 63))
$33 = 9,22337204e+18

(gdb) print (float)(-9223372036854775808)
$39 = 9,22337204e+18
Run Code Online (Sandbox Code Playgroud)

可以看出,即使添加显式强制转换也不能解决问题.我有点困惑,因为float应该能够容纳更大的数字(就绝对值而言).sizeof(float) == 4sizeof(size_t) == 8在情况下,它很重要.似乎值-2 ^ 63是一些魔法限制,因为-2 ^ 63 + 1转换得非常好:

(gdb) print (float)(-((int64_t)1 << 63) + 1)
$44 = -9,22337149e+18
Run Code Online (Sandbox Code Playgroud)

在值<= - 2 ^ 63的转换中,符号丢失的原因是什么?值-2 ^ 63可以用int64_t和float表示; 它可以在上述其他平台上运行.

Wea*_*ane 5

该指令(int64_t)1 << 63将a 1移入符号位,因此是Undefined Behavior.

即使转移成功并且给出了0x8000000000000000可以支持的最小(和负)值,然后用它来否定值

-((int64_t)1 << 63)
Run Code Online (Sandbox Code Playgroud)

将值放在正符号64位的范围之外int.

  • ......这也是未定义的行为.所以每个编译器都绝对正确. (3认同)