[BACK]Return to perfpow.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpz

Diff for /OpenXM_contrib/gmp/mpz/Attic/perfpow.c between version 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2000/09/09 14:12:55 version 1.1.1.2, 2003/08/25 16:06:33
Line 1 
Line 1 
 /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,  /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
    zero otherwise.     zero otherwise.
   
 Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.  Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
   
 This file is part of the GNU MP Library.  This file is part of the GNU MP Library.
   
Line 31  MA 02111-1307, USA. */
Line 31  MA 02111-1307, USA. */
     So for n prime, we readily have a solution.      So for n prime, we readily have a solution.
   * If n is factorable into the non-trivial factors p1,p2,...    * If n is factorable into the non-trivial factors p1,p2,...
     Since m divides n, m has a subset of n's factors and b = n / m.      Since m divides n, m has a subset of n's factors and b = n / m.
   
     BUG: Should handle negative numbers, since they can be odd perfect powers.  
 */  */
   
 /* This is a naive approach to recognizing perfect powers.  /* This is a naive approach to recognizing perfect powers.
Line 64  static const unsigned short primes[] =
Line 62  static const unsigned short primes[] =
   
   
 int  int
 #if __STDC__  
 mpz_perfect_power_p (mpz_srcptr u)  mpz_perfect_power_p (mpz_srcptr u)
 #else  
 mpz_perfect_power_p (u)  
      mpz_srcptr u;  
 #endif  
 {  {
   unsigned long int prime;    unsigned long int prime;
   unsigned long int n, n2;    unsigned long int n, n2;
Line 78  mpz_perfect_power_p (u)
Line 71  mpz_perfect_power_p (u)
   mpz_t u2, q;    mpz_t u2, q;
   int exact;    int exact;
   mp_size_t uns;    mp_size_t uns;
     mp_size_t usize = SIZ (u);
   TMP_DECL (marker);    TMP_DECL (marker);
   
   if (mpz_cmp_ui (u, 1) <= 0)    if (usize == 0)
     return 0;      return 1;                   /* consider 0 a perfect power */
   
   n2 = mpz_scan1 (u, 0);    n2 = mpz_scan1 (u, 0);
   if (n2 == 1)    if (n2 == 1)
     return 0;      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 (marker);    TMP_MARK (marker);
   
   uns = ABSIZ (u) - n2 / BITS_PER_MP_LIMB;    uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
   MPZ_TMP_INIT (q, uns);    MPZ_TMP_INIT (q, uns);
   MPZ_TMP_INIT (u2, uns);    MPZ_TMP_INIT (u2, uns);
   
Line 102  mpz_perfect_power_p (u)
Line 99  mpz_perfect_power_p (u)
     {      {
       prime = primes[i];        prime = primes[i];
       rem = mpz_tdiv_ui (u2, prime);        rem = mpz_tdiv_ui (u2, prime);
       if (rem == 0)             /* divisable? */        if (rem == 0)             /* divisable by this prime? */
         {          {
           rem = mpz_tdiv_q_ui (q, u2, prime * prime);            rem = mpz_tdiv_q_ui (q, u2, prime * prime);
           if (rem != 0)            if (rem != 0)
             {              {
               TMP_FREE (marker);                TMP_FREE (marker);
               return 0;                return 0;         /* prime divides exactly once, reject */
             }              }
           mpz_swap (q, u2);            mpz_swap (q, u2);
           for (n = 2;;)            for (n = 2;;)
Line 120  mpz_perfect_power_p (u)
Line 117  mpz_perfect_power_p (u)
               n++;                n++;
             }              }
   
             if ((n & 1) == 0 && usize < 0)
               {
                 TMP_FREE (marker);
                 return 0;         /* even multiplicity with negative U, reject */
               }
   
           n2 = gcd (n2, n);            n2 = gcd (n2, n);
           if (n2 == 1)            if (n2 == 1)
             {              {
               TMP_FREE (marker);                TMP_FREE (marker);
               return 0;                return 0;         /* we have multiplicity 1 of some factor */
             }              }
   
             if (mpz_cmpabs_ui (u2, 1) == 0)
               {
                 TMP_FREE (marker);
                 return 1;         /* factoring completed; consistent power */
               }
   
           /* As soon as n2 becomes a prime number, stop factoring.            /* As soon as n2 becomes a prime number, stop factoring.
              Either we have u=x^n2 or u is not a perfect power.  */               Either we have u=x^n2 or u is not a perfect power.  */
           if (isprime (n2))            if (isprime (n2))
Line 134  mpz_perfect_power_p (u)
Line 143  mpz_perfect_power_p (u)
         }          }
     }      }
   
   if (mpz_cmp_ui (u2, 1) == 0)  
     {  
       TMP_FREE (marker);  
       return 1;  
     }  
   
   if (n2 == 0)    if (n2 == 0)
     {      {
         /* We found no factors above; have to check all values of n.  */
       unsigned long int nth;        unsigned long int nth;
       /* We did not find any factors above.  We have to consider all values        for (nth = usize < 0 ? 3 : 2;; nth++)
          of n.  */  
       for (nth = 2;; nth++)  
         {          {
           if (! isprime (nth))            if (! isprime (nth))
             continue;              continue;
Line 205  n2prime:
Line 207  n2prime:
 }  }
   
 static unsigned long int  static unsigned long int
 #if __STDC__  
 gcd (unsigned long int a, unsigned long int b)  gcd (unsigned long int a, unsigned long int b)
 #else  
 gcd (a, b)  
      unsigned long int a, b;  
 #endif  
 {  {
   int an2, bn2, n2;    int an2, bn2, n2;
   
Line 249  gcd (a, b)
Line 246  gcd (a, b)
 }  }
   
 static int  static int
 #if __STDC__  
 isprime (unsigned long int t)  isprime (unsigned long int t)
 #else  
 isprime (t)  
      unsigned long int t;  
 #endif  
 {  {
   unsigned long int q, r, d;    unsigned long int q, r, d;
   

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>