Как воспроизвести с плавающей точкой cos(x)!= Cos (x)

Как воспроизвести это поведение? https://isocpp.org/wiki/faq/newbie

Чтобы быть точным, в следующем коде параметры x а также y равны; они могут быть равны 1,0 или любому другому значению.

void foo(double x, double y)
{
  double cos_x = cos(x);
  double cos_y = cos(y);
  // the behavior might depend on what's in here
  if (cos_x != cos_y) {
    std::cout << "Huh?!?\n";  // You might end up here when x == y!!
  }
}

Некоторые параметры компилятора? Loop? Любая идея?

1 ответ

Я бы попытался сделать это так, как это делается в связанном примере: без сохранения результатов во временных переменных. В статье упоминается, что арифметика с плавающей запятой часто вычисляется в регистрах, в которых больше битов, чем в ОЗУ. Если существует, например, только один арифметический регистр с плавающей запятой, то после выполнения cos расчет, результат должен быть сохранен в оперативной памяти, чтобы сделать другой cos расчет. Из статьи:

Предположим, ваш код вычисляет cos(x), затем обрезает полученный результат и сохраняет его во временной переменной, скажем, tmp. Затем он может вычислить cos(y) и (пожалуйста, барабанную дробь) сравнить не усеченный результат cos(y) с tmp, то есть с усеченным результатом cos(x).

Когда вы сохраняете оба результата в переменных (в зависимости от оптимизации и т. Д.), Есть большая вероятность, что результат второго cos расчет также будет сохранен в оперативной памяти до расчета. Поскольку результаты будут усечены таким же образом, они будут сравниваться как ==,

Другие вопросы по тегам