Почему функция pow выдает неправильно значение при степени больше 22?
почему функция pow неправильно считает значение 5 в степени больше чем 22 они вроде и близки , но они заканчиваются не на 0 или 5 !
но если мы например будем использовать функцию pow и например введем значение pow(5, 22) сразу числом 2384185791015625, и умножим его на 5 то все посчитается верно
Ответы (2 шт):
Дело в том, что pow возвращает результат типа double, который из-за неточности вещественных чисел может оказаться, например, 24.999999999999999. Далее, т.к. тип "принимающей" переменной в вашем случае целочисленный, возвращённый double будет тоже преобразован в int (uint64_t), а при преобразовании к целому числу дробная часть отбрасывается.
В результате - 24.9999 может стать просто 24. Чем больше операций - тем больше накапливается ошибка и точность вычислений снижается.
Можете попробовать перемножать интовые числа без использования pow() , в таком случае преобразования типов не будет и точность должна радовать.
Ваш компилятор из всех перегрузок 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 для вычислений и результата я не нашёл. Вам придётся написать собственную функцию.

