编译器或cpu中的64位溢出错误

时间:2014-01-02 20:06:55

标签: c++

这是编译器或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位行为不是我所期望的呢?

2 个答案:

答案 0 :(得分:4)

A double只保留53位尾数,而long long保持64位。您在转换中丢失了底部位。实际上它们是圆形的,这就是为什么你最终得到0x800000000。

答案 1 :(得分:2)

问题是0x7fffffffffffffff无法完全表示为double。最近的值可以是0x8000000000000000

这意味着,当您将0x7fffffffffffffff投放到double时,它会变为9223372036854775808.00x8000000000000000