patches/gmp/4.2.4/120-perfpow.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sun Mar 08 18:04:56 2009 +0000 (2009-03-08)
changeset 1250 7aca73e68147
permissions -rw-r--r--
Add patchset for MGP-4.2.4, from upstream.

/trunk/patches/gmp/4.2.4/120-perfpow.patch | 149 149 0 0 ++++++++++++++++++++++
/trunk/patches/gmp/4.2.4/110-mpf_set_str.patch | 32 32 0 0 +++++
/trunk/patches/gmp/4.2.4/100-mpf_eq.patch | 219 219 0 0 ++++++++++++++++++++++++++++++++
3 files changed, 400 insertions(+)
     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;