Я наблюдал удивительное поведение при тестировании простых арифметических операций в предельных случаях на архитектуре x86:
const double max = 9.9e307; // Near std::numeric_limits<double>::max()
const double init[] = { max, max, max };
const valarray<double> myvalarray(init, 3);
const double mysum = myvalarray.sum();
cout << "Sum is " << mysum << endl; // Sum is 1.#INF
const double myavg1 = mysum/myvalarray.size();
cout << "Average (1) is " << myavg1 << endl; // Average (1) is 1.#INF
const double myavg2 = myvalarray.sum()/myvalarray.size();
cout << "Average (2) is " << myavg2 << endl; // Average (2) is 9.9e+307
(Протестировано с MSVC в режиме выпуска, а также с gcc через Codepad.org. Режим отладки MSVC устанавливает среднее значение (2) в #INF
.)
Я ожидал, что средний (2) будет равен среднему (1), но мне кажется, что встроенный оператор разделения С++ получил оптимизацию от компилятора и каким-то образом помешал накоплению достичь #INF
.
Короче: среднее значение больших чисел не дает #INF
.
Я наблюдал такое же поведение с std-алгоритмом на MSVC:
const double mysum = accumulate(init, init+3, 0.);
cout << "Sum is " << mysum << endl; // Sum is 1.#INF
const double myavg1 = mysum/static_cast<size_t>(3);
cout << "Average (1) is " << myavg1 << endl; // Average (1) is 1.#INF
const double myavg2 = accumulate(init, init+3, 0.)/static_cast<size_t>(3);
cout << "Average (2) is " << myavg2 << endl; // Average (2) is 9.9e+307
(На этот раз gcc устанавливает среднее значение (2) на #INF
: http://codepad.org/C5CTEYHj.)
- Кто-нибудь может объяснить, как этот "эффект" был достигнут?
- Это функция? Или я могу считать это "неожиданным поведением" вместо просто "удивительного"?
Спасибо