Программа С++ возвращает разные результаты в двух IDE

Я пишу следующую 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;
}

Ответы

Ответ 1

Вероятно, вы видите ошибки точности из-за компиляции CodeBlocks в 32-битном режиме и компиляции Eclipse в 64-битном режиме:

$ g++ -m32 test.cpp
$ ./a.out
9183
$ g++ -m64 test.cpp
$ ./a.out
9220

Ответ 2

Если я использую оба аргумента в два раза, я получаю то, что вы ожидаете:

pow(static_cast<double>(a), static_cast<double>(b))

Ответ 3

На самом деле вы не должны полагаться на == (или технически, x <= y && y <= x) для удвоения в любом случае. Таким образом, этот код создает результаты, зависящие от реализации (строго говоря, UB, за комментарии, но что я имел в виду:))

Ответ 4

Разница, по-видимому, связана с тем, используют ли операции с плавающей запятой 53-битную точность или 64-битную точность. Если вы добавите следующие две строки перед циклом (при условии архитектуры Intel), он будет использовать 53-битную точность и даст результат 9220 при компиляции в виде 32-разрядного приложения:

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

Это биты 8 и 9 FPU, которые контролируют эту точность. Вышеуказанное устанавливает эти два бита в 10. Установка их на 11 приводит к 64-битной точности. И только для полноты, если вы установите бит на 00 (значение 0x7f), размер будет напечатан как 9230.