Вопрос:

GCC C ++ Pow точность

c++ gcc mingw pow cmath

1731 просмотра

1 ответ

56 Репутация автора

Итак, я участвовал в компьютерном конкурсе и заметил странную ошибку. Pow (26,2) всегда будет возвращать 675, а иногда 674? хотя правильный ответ - 676. Подобного рода ошибки также случаются с pow (26,3), pow (26,4) и т. д. После некоторой отладки после конкурса я считаю, что ответ связан с тем, что int округляется. Интересно, что такого рода ошибки никогда не случались со мной раньше. Компьютер, на котором у меня был mingw на Windows 8. Версия GCC была довольно новой, как мне кажется, 2-3 месяца назад. Но я обнаружил, что, если я включу флаг оптимизации o1 / o2 / o3, ошибки такого рода чудесным образом исчезнут. Pow (26,2) всегда получит 676 или правильный ответ Может кто-нибудь объяснить, почему?

#include <cmath> 
#include <iostream> 

using namespace std; 
int main() { 
    cout<<pow(26,2)<<endl; 
    cout<<int(pow(26,2))<<endl; 
}

Результаты с удвоениями странные.

double a=26; 
double b=2; 
cout<<int(pow(a,b))<<endl; #outputs 675 
cout<<int(pow(26.0,2.0))<<endl; # outputs 676 
cout<<int(pow(26*1.00,2*1.00))<<endl; # outputs 676
Автор: Michael Chen Источник Размещён: 08.12.2012 05:49

Ответы (1)


11 плюса

21344 Репутация автора

Функция powработает с двумя значениями с плавающей запятой и может возводить одно в другое. Это делается с помощью аппроксимирующего алгоритма, поскольку требуется иметь возможность обрабатывать значения от самых маленьких до самых больших.

Поскольку это аппроксимирующий алгоритм, он иногда получает значение немного неправильно. В большинстве случаев это нормально. Однако, если вы заинтересованы в получении точного результата, не используйте его.

Я бы настоятельно рекомендовал не использовать его для целых чисел. И если второй операнд известен (в данном случае 2), тривиально заменить его кодом, который делает это намного быстрее и возвращает правильное значение. Например:

int square(int x)
{
  return x * x;
}

Чтобы ответить на реальный вопрос: некоторые компиляторы могут заменять вызовы powдругим кодом или исключать их все вместе, когда известен один или оба аргумента. Это объясняет, почему вы получаете разные результаты.

Автор: Lindydancer Размещён: 08.12.2012 08:20
Вопросы из категории :
32x32