patches/gmp/4.2.4/120-perfpow.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Tue Aug 02 18:28:10 2011 +0200 (2011-08-02)
changeset 2590 b64cfb67944e
permissions -rw-r--r--
scripts/functions: svn retrieval first tries the mirror for tarballs

The svn download helper looks for the local tarballs dir to see if it
can find a pre-downloaded tarball, and if it does not find it, does
the actual fetch to upstream via svn.

In the process, it does not even try to get a tarball from the local
mirror, which can be useful if the mirror has been pre-populated
manually (or with a previously downloaded tree).

Fake a tarball get with the standard tarball-download helper, but
without specifying any upstream URL, which makes the helper directly
try the LAN mirror.

Of course, if no mirror is specified, no URL wil be available, and
the standard svn retrieval will kick in.

Reported-by: ANDY KENNEDY <ANDY.KENNEDY@adtran.com>
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
     1 Original patch from: perfpow.c.diff
     2 
     3 -= BEGIN original header =-
     4 Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
     5 
     6 This file is part of the GNU MP Library.
     7 
     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.
    12 
    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.
    17 
    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/.
    20 
    21 -= END original header =-
    22 
    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
    26 @@ -1,7 +1,7 @@
    27  /* mpz_perfect_power_p(arg) -- Return non-zero if ARG is a perfect power,
    28     zero otherwise.
    29  
    30 -Copyright 1998, 1999, 2000, 2001, 2005 Free Software Foundation, Inc.
    31 +Copyright 1998, 1999, 2000, 2001, 2005, 2008 Free Software Foundation, Inc.
    32  
    33  This file is part of the GNU MP Library.
    34  
    35 @@ -59,6 +59,8 @@
    36  #define SMALLEST_OMITTED_PRIME 1009
    37  
    38  
    39 +#define POW2P(a) (((a) & ((a) - 1)) == 0)
    40 +
    41  int
    42  mpz_perfect_power_p (mpz_srcptr u)
    43  {
    44 @@ -72,16 +74,13 @@
    45    mp_size_t usize = SIZ (u);
    46    TMP_DECL;
    47  
    48 -  if (usize == 0)
    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 */
    52  
    53    n2 = mpz_scan1 (u, 0);
    54    if (n2 == 1)
    55      return 0;			/* 2 divides exactly once.  */
    56  
    57 -  if (n2 != 0 && (n2 & 1) == 0 && usize < 0)
    58 -    return 0;			/* 2 has even multiplicity with negative U */
    59 -
    60    TMP_MARK;
    61  
    62    uns = ABS (usize) - n2 / BITS_PER_MP_LIMB;
    63 @@ -89,6 +88,14 @@
    64    MPZ_TMP_INIT (u2, uns);
    65  
    66    mpz_tdiv_q_2exp (u2, u, n2);
    67 +  mpz_abs (u2, u2);
    68 +
    69 +  if (mpz_cmp_ui (u2, 1) == 0)
    70 +    {
    71 +      TMP_FREE;
    72 +      /* factoring completed; consistent power */
    73 +      return ! (usize < 0 && POW2P(n2));
    74 +    }
    75  
    76    if (isprime (n2))
    77      goto n2prime;
    78 @@ -97,6 +104,9 @@
    79      {
    80        prime = primes[i];
    81  
    82 +      if (mpz_cmp_ui (u2, prime) < 0)
    83 +	break;
    84 +
    85        if (mpz_divisible_ui_p (u2, prime))	/* divisible by this prime? */
    86  	{
    87  	  rem = mpz_tdiv_q_ui (q, u2, prime * prime);
    88 @@ -115,12 +125,6 @@
    89  	      n++;
    90  	    }
    91  
    92 -	  if ((n & 1) == 0 && usize < 0)
    93 -	    {
    94 -	      TMP_FREE;
    95 -	      return 0;		/* even multiplicity with negative U, reject */
    96 -	    }
    97 -
    98  	  n2 = gcd (n2, n);
    99  	  if (n2 == 1)
   100  	    {
   101 @@ -128,10 +132,11 @@
   102  	      return 0;		/* we have multiplicity 1 of some factor */
   103  	    }
   104  
   105 -	  if (mpz_cmpabs_ui (u2, 1) == 0)
   106 +	  if (mpz_cmp_ui (u2, 1) == 0)
   107  	    {
   108  	      TMP_FREE;
   109 -	      return 1;		/* factoring completed; consistent power */
   110 +	      /* factoring completed; consistent power */
   111 +	      return ! (usize < 0 && POW2P(n2));
   112  	    }
   113  
   114  	  /* As soon as n2 becomes a prime number, stop factoring.
   115 @@ -169,6 +174,10 @@
   116    else
   117      {
   118        unsigned long int nth;
   119 +
   120 +      if (usize < 0 && POW2P(n2))
   121 +	return 0;
   122 +
   123        /* We found some factors above.  We just need to consider values of n
   124  	 that divides n2.  */
   125        for (nth = 2; nth <= n2; nth++)
   126 @@ -184,8 +193,11 @@
   127  	    exact = mpz_root (q, u2, nth);
   128  	  if (exact)
   129  	    {
   130 -	      TMP_FREE;
   131 -	      return 1;
   132 +	      if (! (usize < 0 && POW2P(nth)))
   133 +		{
   134 +		  TMP_FREE;
   135 +		  return 1;
   136 +		}
   137  	    }
   138  	  if (mpz_cmp_ui (q, SMALLEST_OMITTED_PRIME) < 0)
   139  	    {
   140 @@ -199,6 +211,9 @@
   141      }
   142  
   143  n2prime:
   144 +  if (usize < 0 && POW2P(n2))
   145 +    return 0;
   146 +
   147    exact = mpz_root (NULL, u2, n2);
   148    TMP_FREE;
   149    return exact;