1 Original patch from: perfpow.c.diff
3 -= BEGIN original header =-
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/.
21 -= END original header =-
23 diff -durN gmp-4.2.4.orig/mpz/perfpow.c gmp-4.2.4/mpz/perfpow.c
24 --- gmp-4.2.4.orig/mpz/perfpow.c 2007-08-30 20:31:41.000000000 +0200
25 +++ gmp-4.2.4/mpz/perfpow.c 2009-03-08 18:36:16.000000000 +0100
27 /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
30 -Copyright 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
31 +Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
33 This file is part of the GNU MP Library.
36 #define SMALLEST_OMITTED_PRIME 1009
39 +#define POW2P(a) (((a) & ((a) - 1)) == 0)
42 mpz_perfect_power_p (mpz_srcptr u)
45 mp_size_t usize = SIZ (u);
49 - return 1; /* consider 0 a perfect power */
50 + if (mpz_cmpabs_ui (u, 1) <= 0)
51 + return 1; /* -1, 0, and +1 are perfect powers */
53 n2 = mpz_scan1 (u, 0);
55 return 0; /* 2 divides exactly once. */
57 - if (n2 != 0 && (n2 & 1) == 0 && usize < 0)
58 - return 0; /* 2 has even multiplicity with negative U */
62 uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
64 MPZ_TMP_INIT (u2, uns);
66 mpz_tdiv_q_2exp (u2, u, n2);
69 + if (mpz_cmp_ui (u2, 1) == 0)
72 + /* factoring completed; consistent power */
73 + return ! (usize < 0 && POW2P(n2));
82 + if (mpz_cmp_ui (u2, prime) < 0)
85 if (mpz_divisible_ui_p (u2, prime)) /* divisible by this prime? */
87 rem = mpz_tdiv_q_ui (q, u2, prime * prime);
92 - if ((n & 1) == 0 && usize < 0)
95 - return 0; /* even multiplicity with negative U, reject */
101 @@ -128,10 +132,11 @@
102 return 0; /* we have multiplicity 1 of some factor */
105 - if (mpz_cmpabs_ui (u2, 1) == 0)
106 + if (mpz_cmp_ui (u2, 1) == 0)
109 - return 1; /* factoring completed; consistent power */
110 + /* factoring completed; consistent power */
111 + return ! (usize < 0 && POW2P(n2));
114 /* As soon as n2 becomes a prime number, stop factoring.
118 unsigned long int nth;
120 + if (usize < 0 && POW2P(n2))
123 /* We found some factors above. We just need to consider values of n
125 for (nth = 2; nth <= n2; nth++)
127 exact = mpz_root (q, u2, nth);
132 + if (! (usize < 0 && POW2P(nth)))
138 if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
144 + if (usize < 0 && POW2P(n2))
147 exact = mpz_root (NULL, u2, n2);