Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.

This file is part of the GNU MP Library.

The GNU MP Library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

The GNU MP Library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.

Index: mpz/perfpow.c
===================================================================
RCS file: /home/cvsfiles/gmp42/mpz/perfpow.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -p -2 -r1.2 -r1.3
*** mpz/perfpow.c	30 Aug 2007 18:19:44 -0000	1.2
--- mpz/perfpow.c	26 Dec 2008 19:46:24 -0000	1.3
***************
*** 2,6 ****
     zero otherwise.
  
! Copyright 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
  
  This file is part of the GNU MP Library.
--- 2,6 ----
     zero otherwise.
  
! Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
  
  This file is part of the GNU MP Library.
*************** static const unsigned short primes[] =
*** 60,63 ****
--- 60,65 ----
  
  
+ #define POW2P(a) (((a) & ((a) - 1)) == 0)
+ 
  int
  mpz_perfect_power_p (mpz_srcptr u)
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 73,78 ****
    TMP_DECL;
  
!   if (usize == 0)
!     return 1;			/* consider 0 a perfect power */
  
    n2 = mpz_scan1 (u, 0);
--- 75,80 ----
    TMP_DECL;
  
!   if (mpz_cmpabs_ui (u, 1) <= 0)
!     return 1;			/* -1, 0, and +1 are perfect powers */
  
    n2 = mpz_scan1 (u, 0);
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 80,86 ****
      return 0;			/* 2 divides exactly once.  */
  
-   if (n2 != 0 && (n2 & 1) == 0 && usize < 0)
-     return 0;			/* 2 has even multiplicity with negative U */
- 
    TMP_MARK;
  
--- 82,85 ----
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 90,93 ****
--- 89,100 ----
  
    mpz_tdiv_q_2exp (u2, u, n2);
+   mpz_abs (u2, u2);
+ 
+   if (mpz_cmp_ui (u2, 1) == 0)
+     {
+       TMP_FREE;
+       /* factoring completed; consistent power */
+       return ! (usize < 0 && POW2P(n2));
+     }
  
    if (isprime (n2))
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 98,101 ****
--- 105,111 ----
        prime = primes[i];
  
+       if (mpz_cmp_ui (u2, prime) < 0)
+ 	break;
+ 
        if (mpz_divisible_ui_p (u2, prime))	/* divisible by this prime? */
  	{
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 116,125 ****
  	    }
  
- 	  if ((n & 1) == 0 && usize < 0)
- 	    {
- 	      TMP_FREE;
- 	      return 0;		/* even multiplicity with negative U, reject */
- 	    }
- 
  	  n2 = gcd (n2, n);
  	  if (n2 == 1)
--- 126,129 ----
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 129,136 ****
  	    }
  
! 	  if (mpz_cmpabs_ui (u2, 1) == 0)
  	    {
  	      TMP_FREE;
! 	      return 1;		/* factoring completed; consistent power */
  	    }
  
--- 133,141 ----
  	    }
  
! 	  if (mpz_cmp_ui (u2, 1) == 0)
  	    {
  	      TMP_FREE;
! 	      /* factoring completed; consistent power */
! 	      return ! (usize < 0 && POW2P(n2));
  	    }
  
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 170,173 ****
--- 175,182 ----
      {
        unsigned long int nth;
+ 
+       if (usize < 0 && POW2P(n2))
+ 	return 0;
+ 
        /* We found some factors above.  We just need to consider values of n
  	 that divides n2.  */
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 185,190 ****
  	  if (exact)
  	    {
! 	      TMP_FREE;
! 	      return 1;
  	    }
  	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
--- 194,202 ----
  	  if (exact)
  	    {
! 	      if (! (usize < 0 && POW2P(nth)))
! 		{
! 		  TMP_FREE;
! 		  return 1;
! 		}
  	    }
  	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
*************** mpz_perfect_power_p (mpz_srcptr u)
*** 200,203 ****
--- 212,218 ----
  
  n2prime:
+   if (usize < 0 && POW2P(n2))
+     return 0;
+ 
    exact = mpz_root (NULL, u2, n2);
    TMP_FREE;
