Finding integer power roots

僤鯓⒐⒋嵵緔 提交于 2019-12-12 10:37:15

问题


What is the best (most efficient) algorithm for finding all integer power roots of a number?

That is, given a number n, I want to find b (base) and e (exponent) such that

n = be

I want to obtain all the possible value pairs of b and e

Ps: n b and e are to be positive integers .


回答1:


I think brute force approach should work: try all es from 2 (1 is a trivial solution) and up, taking r = n ^ 1/e, a double. If r is less than 2, stop. Otherwise, compute ceil(r)^e and floor(r)^e, and compare them to n (you need ceil and floor to compensate for errors in floating point representations). Assuming your integers fit in 64 bits, you would not need to try more than 64 values of e.

Here is an example in C++:

#include <iostream>
#include <string>
#include <sstream>
#include <math.h>
typedef long long i64;
using namespace std;
int main(int argc, const char* argv[]) {
    if (argc == 0) return 0;
    stringstream ss(argv[1]);
    i64 n;
    ss >> n;
    cout << n << ", " << 1 << endl;
    for (int e = 2 ; ; e++) {
        double r = pow(n, 1.0 / e);
        if (r < 1.9) break;
        i64 c = ceil(r);
        i64 f = floor(r);
        i64 p1 = 1, p2 = 1;
        for (int i = 0 ; i != e ; i++, p1 *= c, p2 *= f);
        if (p1 == n) {
            cout << c << ", " << e << endl;
        } else if (p2 == n) {
            cout << f << ", " << e << endl;
        }
    }
    return 0;
}

When invoked with 65536, it produces this output:

65536, 1
256, 2
16, 4
4, 8
2, 16



回答2:


First find the prime factorization of n: n = p1e1 p2e2 p3e3 ...

Then find the greatest common divisor g of e1, e2, e3, ... by using the Euclidean algorithm.

Now for any factor e of g, you can use:

b = p1e1/e p2e2/e p3e3/e ...

And you have n = be.




回答3:


It depends on the dimensions of the task whether my approach will suite your needs.

First of all there is one obvious solution: e = 1, right? From then on if you want to find all the solutions: all the algorithms I can think of require to find some prime factor of n. If this is just a single independent task nothing better than brute force on the primes can be done (if I am not wrong). After you find the first prime factor p and its corresponding exponent (i.e the highest number k such that p^k / n) you need to check for e only the divisors of k. For every such exponent l (again l iterates all divisors of k) you can use binary search to see if the lth root of n is integer (equivalent to finding new solution).




回答4:


Mix the approaches of interjay and dasblinkenlight. First find all small prime factors (if any) and their exponents in the prime factorisation of n. The appropriate value of 'small' depends on n, for medium sized n, p <= 100 can be sufficient, for large n, p <= 10000 or p <= 10^6 may be more appropriate. If you find any small prime factors, you know that e must divide the greatest common divisor of all exponents you found. Quite often, that gcd will be 1. Anyway, the range of possible exponents will be reduced, if n has no small prime factors, you know that e <= log(n)/log(small_limit), which is a good reduction from log(n)/log(2), if you have found a couple of small prime factors, the gcd of their exponents is g, and the remaining cofactor of n is m, you only need to check the divisors of g not exceeding log(m)/log(small_limit).



来源:https://stackoverflow.com/questions/8635067/finding-integer-power-roots

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!