当我在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版本如下所示:
最后一个问题是:如何使用扩展浮点?似乎vs2012只提供64位双倍。还有更长的选择吗?