1 /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
4 Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
22 We are to determine if c is a perfect power, c = a ^ b.
23 Assume c is divisible by 2^n and that codd = c/2^n is odd.
24 Assume a is divisible by 2^m and that aodd = a/2^m is odd.
25 It is always true that m divides n.
27 * If n is prime, either 1) a is 2*aodd and b = n
28 or 2) a = c and b = 1.
29 So for n prime, we readily have a solution.
30 * If n is factorable into the non-trivial factors p1,p2,...
31 Since m divides n, m has a subset of n's factors and b = n / m.
34 /* This is a naive approach to recognizing perfect powers.
35 Many things can be improved. In particular, we should use p-adic
36 arithmetic for computing possible roots. */
38 #include <stdio.h> /* for NULL */
43 static unsigned long int gcd __GMP_PROTO ((unsigned long int, unsigned long int));
44 static int isprime __GMP_PROTO ((unsigned long int));
46 static const unsigned short primes[] =
47 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53,
48 59, 61, 67, 71, 73, 79, 83, 89, 97,101,103,107,109,113,127,131,
49 137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,
50 227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,
51 313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,
52 419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,
53 509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,
54 617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,
55 727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,
56 829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,
57 947,953,967,971,977,983,991,997,0
59 #define SMALLEST_OMITTED_PRIME 1009
62 #define POW2P(a) (((a) & ((a) - 1)) == 0)
65 mpz_perfect_power_p (mpz_srcptr u)
67 unsigned long int prime;
68 unsigned long int n, n2;
70 unsigned long int rem;
74 mp_size_t usize = SIZ (u);
77 if (mpz_cmpabs_ui (u, 1) <= 0)
78 return 1; /* -1, 0, and +1 are perfect powers */
80 n2 = mpz_scan1 (u, 0);
82 return 0; /* 2 divides exactly once. */
86 uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
87 MPZ_TMP_INIT (q, uns);
88 MPZ_TMP_INIT (u2, uns);
90 mpz_tdiv_q_2exp (u2, u, n2);
93 if (mpz_cmp_ui (u2, 1) == 0)
96 /* factoring completed; consistent power */
97 return ! (usize < 0 && POW2P(n2));
103 for (i = 1; primes[i] != 0; i++)
107 if (mpz_cmp_ui (u2, prime) < 0)
110 if (mpz_divisible_ui_p (u2, prime)) /* divisible by this prime? */
112 rem = mpz_tdiv_q_ui (q, u2, prime * prime);
116 return 0; /* prime divides exactly once, reject */
121 rem = mpz_tdiv_q_ui (q, u2, prime);
132 return 0; /* we have multiplicity 1 of some factor */
135 if (mpz_cmp_ui (u2, 1) == 0)
138 /* factoring completed; consistent power */
139 return ! (usize < 0 && POW2P(n2));
142 /* As soon as n2 becomes a prime number, stop factoring.
143 Either we have u=x^n2 or u is not a perfect power. */
151 /* We found no factors above; have to check all values of n. */
152 unsigned long int nth;
153 for (nth = usize < 0 ? 3 : 2;; nth++)
158 exact = mpz_padic_root (q, u2, nth, PTH);
161 exact = mpz_root (q, u2, nth);
167 if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
176 unsigned long int nth;
178 if (usize < 0 && POW2P(n2))
184 /* We found some factors above. We just need to consider values of n
186 for (nth = 2; nth <= n2; nth++)
193 exact = mpz_padic_root (q, u2, nth, PTH);
196 exact = mpz_root (q, u2, nth);
199 if (! (usize < 0 && POW2P(nth)))
205 if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
217 if (usize < 0 && POW2P(n2))
223 exact = mpz_root (NULL, u2, n2);
228 static unsigned long int
229 gcd (unsigned long int a, unsigned long int b)
238 count_trailing_zeros (an2, a);
241 count_trailing_zeros (bn2, b);
253 while ((a & 1) == 0);
260 while ((b & 1) == 0);
268 isprime (unsigned long int t)
270 unsigned long int q, r, d;
272 if (t < 3 || (t & 1) == 0)
275 for (d = 3, r = 1; r != 0; d += 2)