Как воспроизвести с плавающей точкой 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
расчет также будет сохранен в оперативной памяти до расчета. Поскольку результаты будут усечены таким же образом, они будут сравниваться как ==
,