15

我在里面写了下面的c++程序CodeBlocks,结果是9183。我又写进去Eclipse,运行后返回9220。两者都使用MinGW。正确的结果是 9183。这段代码有什么问题?谢谢。源代码:

#include <iostream>
#include <set>
#include <cmath>

int main()
{
   using namespace std;
   set<double> set_1;
   for(int a = 2; a <= 100; a++)
   {
       for(int b = 2; b <= 100; b++)
       {
           set_1.insert(pow(double(a), b));
       }
   }
    cout << set_1.size();

return 0;
}
4

4 回答 4

11

由于 CodeBlocks 在 32 位模式下编译和 Eclipse 在 64 位模式下编译,您可能会看到精度错误:

$ g++ -m32 test.cpp
$ ./a.out
9183
$ g++ -m64 test.cpp
$ ./a.out
9220
于 2012-11-29T22:16:34.160 回答
3

如果我将两个参数都转换为 double 我会得到你所期望的:

pow(static_cast<double>(a), static_cast<double>(b))
于 2012-11-29T22:23:59.873 回答
3

差异似乎是由于浮点运算使用的是 53 位精度还是 64 位精度。如果在循环前面添加以下两行(假设 Intel 架构),它将使用 53 位精度并9220在编译为 32 位应用程序时给出结果:

uint16_t precision = 0x27f;
asm("fldcw %0" : : "m" (*&precision));

控制此精度的是 FPU 的第 8 位和第 9 位。上面将这两个位设置为10. 将它们设置为1164 位精度。而且,为了完整起见,如果将位设置为00(值 0x7f),则大小将打印为9230.

于 2012-11-29T23:01:06.960 回答
2

实际上,无论如何,您实际上不应该依赖==(或技术上x <= y && y <= x)双打。所以这段代码会产生依赖于实现的结果(严格来说不是 UB,根据评论,但我的意思是 :))

于 2012-11-29T22:07:52.920 回答