-1

Код

значения

почему функция pow неправильно считает значение 5 в степени больше чем 22 они вроде и близки , но они заканчиваются не на 0 или 5 !

но если мы например будем использовать функцию pow и например введем значение pow(5, 22) сразу числом 2384185791015625, и умножим его на 5 то все посчитается верно

2 Answers2

2

Дело в том, что pow возвращает результат типа double, который из-за неточности вещественных чисел может оказаться, например, 24.999999999999999. Далее, т.к. тип "принимающей" переменной в вашем случае целочисленный, возвращённый double будет тоже преобразован в int (uint64_t), а при преобразовании к целому числу дробная часть отбрасывается.

В результате - 24.9999 может стать просто 24. Чем больше операций - тем больше накапливается ошибка и точность вычислений снижается.

Можете попробовать перемножать интовые числа без использования pow() , в таком случае преобразования типов не будет и точность должна радовать.

dresqd
  • 560
2

Ваш компилятор из всех перегрузок std::pow выбирает ту что работает с double:

double pow(double base, double exp);

double способен точно представлять целые числа в диапазоне [1, 253) - в мантиссе вещественного числа 53 бита. Если целое больше чем 253, оно округляется - младшие биты тем или иным способом исключаются/удаляются/округляются. Проверка:

522 = 2384185791015625 < 9007199254740992 = 253 - это число может быть представлено точно.

523 = 11920928955078125 > 9007199254740992 = 253 - это число "не помещается в разрядную сетку" и будет округлено, что вы и видите.

Способа заставить std::pow использовать uint64_t для вычислений и результата я не нашёл. Вам придётся написать собственную функцию.