Выполняя домашнее задание, я заметил нечто действительно странное, что просто не могу понять, почему.
int x = 5;
cout << pow(x, 2);
Результат 25. Это нормально. Но если я напишу ту же программу, как это:
int x = 5;
int y = pow(x, 2);
cout << y;
Результат 24!
Когда х равен 2, 3, 4, 6, 7, 8, нет проблем, но с 5, 10, 11, 13 и т. Д. Результат на 1 ниже, чем должен быть.
То же самое с if ().
for (int x = 1; x <= 20 ; x++) {
if (x * x == pow(x, 2))
cout << x << endl;
}
Распечатывает номера 1, 2, 3, 4, 6, 8, 12, 16.
std::pow()
возвращает число с плавающей запятой. Если результат, например, 24.99999999
и вы бросили его int
будет отрезано до 24
,
И это то, что вы делаете во втором примере кода.
cout
не конвертируется в int
и выводит правильный результат в первом примере кода.
«pow» возвращает двойное значение, а не int. Двойное значение усекается, когда приводится как int.
http://www.cplusplus.com/reference/cmath/pow/
Сравнение double с int не рекомендуется.
http://www.cplusplus.com/reference/cmath/pow/
Незначительное редактирование вашего кода для работы:
int x = 5;
double y = pow(x,2); // correct datatype
cout << y;
функция Pow работает с float
а также double
, а не целые числа. Когда вы присваиваете это целое число, значение может быть усечено, так как данные с плавающей запятой имеют проблемы с точностью в своем представлении.
Я рекомендую прочитать Что каждый компьютерщик должен знать об арифметике с плавающей точкой, как это описывает Зачем Вы видите это поведение.
Это, как говорится, если вы работаете с double
значения вместо int
вы, скорее всего, увидите ожидаемые результаты.
Функция pow () обычно реализуется в математической библиотеке, возможно, с использованием специальных инструкций в целевом процессоре, для x86 см. Как сделать: Pow (реальный, реальный) в x86. Тем не менее, такие инструкции, как fyl2x
а также f2xm1
не быстрые, поэтому все это может занять 100 тактов процессора. По соображениям производительности компилятор типа gcc предоставляет «встроенные» функции, которые обеспечивают снижение прочности выполнять вычисления быстрее в особых случаях. Когда сила N
является целым числом (как в вашем случае) и маленьким (как в вашем случае), то это умножается быстрее N
раз, чем вызывать библиотечную функцию.
Для выявления случаев, когда мощность является целым числом, математическая библиотека предоставляет перегруженные функции, например double pow(double,int)
, Вы обнаружите, что GCC преобразует
double x = std::pow(y,4);
внутренне на 2 умножения, что намного быстрее, чем вызов библиотеки, и дает точный целочисленный результат, ожидаемый, когда оба операнда являются целыми числами
double tmp = y * y;
double x = tmp * tmp;
для того, чтобы получить этот тип снижения прочности, вы должны
std::pow()
чтобы убедиться, что это версия, которую вы получаете, а не версия из math.hЗатем вы будете соответствовать перегруженной функции Pow в < cmath> который выглядит так
inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); }
Обратите внимание, что эта функция реализована с __builtin_powi
который знает уменьшение силы pow () до умножения, когда степень представляет собой небольшое целое число.