Pow () рассчитывает неправильно? - PullRequest
4 голосов
/ 18 ноября 2011

Мне нужно использовать pow в моей программе на c ++, и если я вызываю функцию pow() следующим образом:

long long test = pow(7, e);

Где

e является целочисленным значением со значением 23.

Я всегда получаю 821077879 в результате. Если я вычисляю это с помощью калькулятора Windows, я получаю 27368747340080916343 .. Что здесь не так? ):

Я пытался привести к разным типам, но здесь ничего не помогло ... Что может быть причиной этого? Как я могу использовать pow() правильно?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 18 ноября 2011

Результат не помещается в long long.

Если вы хотите иметь дело с очень большими числами, используйте библиотеку типа GMP

Или сохранитеэто как плавающая точка (которая не будет такой точной).

Применение по модулю:

const unsigned int b = 5; // base
const unsigned int e = 27; // exponent
const unsigned int m = 7; // modulo

unsigned int r = 1; // remainder

for (int i = 0; i < e; ++i)
  r = (r * b) % m;

// r is now (pow(5,27) % 7)
6 голосов
/ 18 ноября 2011

7 23 слишком велик, чтобы поместиться в long long (при условии, что он 64-битный). Значение становится усеченным.

Редактировать: О, почему вы не сказали, что вы хотели pow(b, e) % m вместо просто pow(b, e)? Это делает все намного проще, потому что вам не нужны bigints в конце концов. Просто сделай весь свой арифметический мод m. Решение Пабби работает, но вот более быстрое (O (log e) вместо O (e)).

unsigned int powmod(unsigned int b, unsigned int e, unsigned int m)
{
   assert(m != 0);

   if (e == 0)
   {
      return 1;
   }
   else if (e % 2 == 0)
   {
      unsigned int squareRoot = powmod(b, e / 2, m);
      return (squareRoot * squareRoot) % m;
   }
   else
   {
      return (powmod(b, e - 1, m) * b) % m;
   }
}
4 голосов
/ 18 ноября 2011

Посмотреть вживую: https://ideone.com/YsG7V

#include<iostream>
#include<cmath>
int main()
{
    long double ldbl = pow(7, 23);
         double dbl  = pow(7, 23);
    std::cout << ldbl << ", " << dbl << std::endl;
}

Выход: 2.73687e + 19, 2.73687e + 19

...