64-битная — с ++ exp функция разные результаты под x64 на i7-3770 и i7-4790

Когда я выполняю простое приложение x64 со следующим кодом, я получаю разные результаты на ПК с Windows с процессором i7-3770 и i7-4790.

#include <cmath>
#include <iostream>
#include <limits>

void main()
{
double val = exp(-10.240990982718174);
std::cout.precision(std::numeric_limits<double>::max_digits10);
std::cout << val;
}

Результат на i7-3770:

3.5677476354876406e-05

Результат на i7-4790:

3.5677476354876413e-05

Когда я изменяю код для вызова

unsigned int control_word;
_controlfp_s(&control_word, _RC_UP, MCW_RC);

до вызова функции exp оба процессора выдают одинаковые результаты.

Мои вопросы:

  • У кого-нибудь есть идея по причине различий между i7-3770 и i7-4790?
  • Есть ли способ установить точность или согласованность с плавающей точкой в ​​проекте Visual Studio 2015/2017 C ++ для всего проекта, а не только для следующего вызова функции? Параметр «Модель с плавающей точкой» (/ fp) не влияет на результаты.

0

Решение

Предполагая, что double кодируется с использованием IEEE-754, и используя это десятичный в двоичный преобразователь, ты это видишь:

3.5677476354876406e-05 представлен в гекса как 0x3F02B48CC0D0ABA8
3.5677476354876413e-05 представлен в гекса как 0x3F02B48CC0D0ABA9

которые отличаются только последним битом, вероятно, из-за ошибки округления.

2

Другие решения

Я провел дальнейшие расследования и выяснил следующие факты:

  • проблема также возникает в Windows с другим компилятором (Intel)
  • в системе Linux оба значения равны

Я также разместил этот вопрос в сообществе Visual Studio. Я получил информацию, что Haswell и более новые процессоры используют FMA3. Вы можете отключить эту функцию с _set_FMA3_enable (0) в начале программы. Когда я делаю это, результаты совпадают.

0

По вопросам рекламы [email protected]