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

32ビットモードでコンパイルされているCodeBlocksと64ビットモードでコンパイルされているEclipseが原因で、精度エラーが発生している可能性があります。

$ 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 ビット精度のどちらを使用しているかによるものと思われます。ループの前に次の 2 行を追加すると (Intel アーキテクチャを想定)、53 ビットの精度が使用9220され、32 ビット アプリケーションとしてコンパイルされたときに結果が得られます。

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

この精度を制御するのは、FPU のビット 8 と 9 です。上記は、これらの 2 つのビットを に設定し10ます。11これらを64 ビット精度に設定すると、結果は 64 ビットになります。そして、完全を期すために、ビットを00(値 0x7f) に設定すると、サイズは として出力され9230ます。

于 2012-11-29T23:01:06.960 に答える
2

実際には、とにかく doubleに==(または技術的に)依存することは想定されていません。x <= y && y <= xしたがって、このコードは実装に依存する結果を生成します(厳密に言えば、コメントごとにUBではありませんが、私が意味したこと:))

于 2012-11-29T22:07:52.920 に答える