我试图将一个整数转换为像这样的浮点数(简化): int64_t x = -((int64_t)1 63);float y = x; 使用64位Windows 7上的MSVC 2013,这可以正常工作,但在Ubuntu 14.04 64位上使用gcc 4.8,我得到x的正值.我禁用了所
int64_t x = -((int64_t)1 << 63); float y = x;
使用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
可以看出,即使添加显式强制转换也不能解决问题.我有点困惑,因为浮点数应该能够容纳更大的数字(就绝对值而言). sizeof(float)== 4和sizeof(size_t)== 8以防万一.似乎值-2 ^ 63是一些魔法限制,因为-2 ^ 63 1被完美地转换为:
(gdb) print (float)(-((int64_t)1 << 63) + 1) $44 = -9,22337149e+18
在值<= - 2 ^ 63的转换中,符号丢失的原因是什么?值-2 ^ 63可以用int64_t和float表示;它可以在上述其他平台上运行.
指令(int64_t)1<< 63将1移入符号位,因此是Undefined Behavior. 即使转换成功并给出0x8000000000000000这是可以支持的最小(和负)值,所以然后取消值-((int64_t)1 << 63)
将值放在正有符号64位int的范围之外.