编译器或CPU中的错误,还是不是错误(我在Windows上使用Visual Studio 2010)?
我有这个测试程序:
{
puts("===========================");
puts("Long Long");
long long maxInt = 0x7fffffffffffffff;
if (maxInt * 1.0 + 0.5 > 0x7fffffffffffffff)
puts("Greater");
else
puts("Not Greater");
long long newVal = maxInt * 1.0 + 0.5;
if (newVal == 0x8000000000000000)
puts("It is 0x8000000000000000");
else
puts("is NOT 0x8000000000000000");
}
{
puts("===========================");
puts("int");
int maxInt = 0x7fffffff;
if (maxInt * 1.0 + 0.5 > 0x7fffffff)
puts("Greater");
else
puts("Not Greater");
int newVal = maxInt * 1.0 + 0.5;
if (newVal == 0x80000000)
puts("It is 0x80000000");
else
puts("is NOT 0x80000000");
}
当我运行它时,我看到以下输出:
===========================
Long Long
Not Greater
It is 0x8000000000000000
===========================
int
Greater
is NOT 0x80000000
我假设"大于"比较投射到float
,或者可能是double
。 但是当第一次比较说"不大"时,那么我希望演员表"长长",将获得0x7fffffffffffffff
值而不是溢出到0x8000000000000000
。
有了int
一切都按照我的期望工作。
那么为什么 64 位行为不是我所期望的呢?
一个double
只容纳53位尾数,而long long
容纳64位。您将在转换中丢失底部位。事实上,他们正在四舍五入,这就是为什么你最终会得到0x800000000。
问题是0x7fffffffffffffff
不能完全表示为double
。最接近的值是 0x8000000000000000
。
这意味着当你投0x7fffffffffffffff
double
的那一刻,它就变成了 9223372036854775808.0
,或0x8000000000000000
。