【发布时间】:2015-05-06 14:09:39
【问题描述】:
我正在尝试将整数转换为这样的浮点数(简化):
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
可以看出,即使添加显式转换也无法解决问题。我有点困惑,因为float 应该能够容纳更大的数字(就绝对值而言)。 sizeof(float) == 4 和 sizeof(size_t) == 8 以防万一。似乎值 -2^63 是一些神奇的限制,因为 -2^63+1 转换得非常好:
(gdb) print (float)(-((int64_t)1 << 63) + 1)
$44 = -9,22337149e+18
值
【问题讨论】:
-
(int64_t)1 << 63将1移入符号位,因此是未定义行为。 -
@WeatherVane:啊,感谢您指出这一点。它现在适用于
(gdb) print (float)(-(int64_t)((uint64_t)1 << 63)) $48 = -9,22337204e+18 -
记住
float只有一个24位尾数! -
只需使用
INT64_MIN并避免任何位移问题。 -
如果可能,在否定之前进行强制转换。 2^63 和 -(2^63) 都可以用浮点数表示。
标签: c floating-point integer type-conversion