Странный пух (х, у); поведение

Выполняя домашнее задание, я заметил нечто действительно странное, что просто не могу понять, почему.

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.

4

Решение

std::pow() возвращает число с плавающей запятой. Если результат, например, 24.99999999 и вы бросили его intбудет отрезано до 24,

И это то, что вы делаете во втором примере кода.
cout не конвертируется в int и выводит правильный результат в первом примере кода.

10

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

«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;
6

функция Pow работает с float а также double, а не целые числа. Когда вы присваиваете это целое число, значение может быть усечено, так как данные с плавающей запятой имеют проблемы с точностью в своем представлении.

Я рекомендую прочитать Что каждый компьютерщик должен знать об арифметике с плавающей точкой, как это описывает Зачем Вы видите это поведение.

Это, как говорится, если вы работаете с double значения вместо intвы, скорее всего, увидите ожидаемые результаты.

5

Функция 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;

для того, чтобы получить этот тип снижения прочности, вы должны

  1. скомпилировать с оптимизацией -O2
  2. явно вызвать функцию pow в библиотеке std::pow() чтобы убедиться, что это версия, которую вы получаете, а не версия из math.h

Затем вы будете соответствовать перегруженной функции Pow в < cmath> который выглядит так

inline double pow(double __x, int __i) { return __builtin_powi(__x, __i); }

Обратите внимание, что эта функция реализована с __builtin_powi который знает уменьшение силы pow () до умножения, когда степень представляет собой небольшое целое число.

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