c ++,vs2012中浮点截断和舍入的不一致性

时间:2015-07-01 03:05:33

标签: c++ visual-studio-2012 floating-point

当我在vs2012中测试截断和四舍五入的行为时,我发现了一些非常奇怪的东西:

const double a = 0x3f ffff ffff ffff;

'a'稍微超出double的精度(最大值为52),将'a'转换回long long类型将获得0x3f ffff ffff fffe。但是IEEE 754为浮点指定了舍入到偶数标准,因此正确的数字应该是0x40 0000 0000 0000。

此外,如果a = 0x 7f ffff ffff ffff,则'(long long)a'将为0x 80 0000 0000 0000.与第一个示例相比,截断行为不同。

然后我再试一次。

const double a = 0x3f ffff ffff fffe;
const double b = 1;
const double c = a + b;

这一次,'c'是0x40 0000 0000 0000.有谁知道为什么会出现这种不一致的情况?

我正在研究几何程序,并且舍入行为对于错误估计非常重要。非常感谢。

********************************************更新2015.7。 1 *****************************************

当我尝试重现此问题时,我意识到这可能是一个错误。

#include <iostream>
#include <cstdint>

using std::int64_t;
using std::cout;
using std::endl;

int main()
{
    const int64_t big1 = 0x3fffffffffffff;
    const int64_t big2 = 0x7fffffffffffff;

    const double float1 = big1;
    const double float2 = big2;

    const int64_t *ptr1 = reinterpret_cast<const int64_t*>(&float1);
    const int64_t *ptr2 = reinterpret_cast<const int64_t*>(&float2);

    cout << std::hex;

    cout << *ptr1 << endl;
    cout << *ptr2 << endl;

    system("pause");
    return 0;
}

输出结果为:

434f ffff ffff ffff
4360 0000 0000 0000

另一个测试程序是:

#include <iostream>
#include <cstdint>

using std::int64_t;
using std::cout;
using std::endl;

int main()
{
    const int64_t big [] = {
        0xfffffffffffff, 
        0x1fffffffffffff, 
        0x3fffffffffffff, 
        0x7fffffffffffff, 
        0xffffffffffffff,
    };

    const double float0 = big[0];
    const double float1 = big[1];
    const double float2 = big[2];
    const double float3 = big[3];
    const double float4 = big[4];

    const int64_t *ptr0 = reinterpret_cast<const int64_t*>(&float0);
    const int64_t *ptr1 = reinterpret_cast<const int64_t*>(&float1);
    const int64_t *ptr2 = reinterpret_cast<const int64_t*>(&float2);
    const int64_t *ptr3 = reinterpret_cast<const int64_t*>(&float3);
    const int64_t *ptr4 = reinterpret_cast<const int64_t*>(&float4);

    cout << std::hex;

    cout << *ptr0 << endl;
    cout << *ptr1 << endl;
    cout << *ptr2 << endl;
    cout << *ptr3 << endl;
    cout << *ptr4 << endl;

    system("pause");
    return 0;
}

输出结果为:

432f ffff ffff fffe
433f ffff ffff ffff
4350 0000 0000 0000
4360 0000 0000 0000
4370 0000 0000 0000

这两个程序为0x3f ffff ffff ffff提供了不同的浮点转换!

我的平台是Win8.1,Intel i5-4200。我在Win32平台和x64平台上使用发布和调试模式编译,并得到了相同的结果。我的VS2012版本如下所示:

vs version info

最后一个问题是:如何使用扩展浮点?似乎vs2012只提供64位双倍。还有更长的选择吗?

0 个答案:

没有答案