github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-perfpow.c (about)

     1  /* Test mpz_perfect_power_p.
     2  
     3     Contributed to the GNU project by Torbjorn Granlund and Martin Boij.
     4  
     5  Copyright 2008-2010, 2014 Free Software Foundation, Inc.
     6  
     7  This file is part of the GNU MP Library test suite.
     8  
     9  The GNU MP Library test suite is free software; you can redistribute it
    10  and/or modify it under the terms of the GNU General Public License as
    11  published by the Free Software Foundation; either version 3 of the License,
    12  or (at your option) any later version.
    13  
    14  The GNU MP Library test suite is distributed in the hope that it will be
    15  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    17  Public License for more details.
    18  
    19  You should have received a copy of the GNU General Public License along with
    20  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    21  
    22  #include <stdio.h>
    23  #include <stdlib.h>
    24  
    25  #include "gmp.h"
    26  #include "gmp-impl.h"
    27  #include "tests.h"
    28  
    29  struct
    30  {
    31    const char *num_as_str;
    32    char want;
    33  } static tests[] =
    34    {
    35      { "0", 1},
    36      { "1", 1},
    37      {"-1", 1},
    38      { "2", 0},
    39      {"-2", 0},
    40      { "3", 0},
    41      {"-3", 0},
    42      { "4", 1},
    43      {"-4", 0},
    44      { "64", 1},
    45      {"-64", 1},
    46      { "128", 1},
    47      {"-128", 1},
    48      { "256", 1},
    49      {"-256", 0},
    50      { "512", 1},
    51      {"-512", 1},
    52      { "0x4000000", 1},
    53      {"-0x4000000", 1},
    54      { "0x3cab640", 1},
    55      {"-0x3cab640", 0},
    56      { "0x3e23840", 1},
    57      {"-0x3e23840", 0},
    58      { "0x3d3a7ed1", 1},
    59      {"-0x3d3a7ed1", 1},
    60      { "0x30a7a6000", 1},
    61      {"-0x30a7a6000", 1},
    62      { "0xf33e5a5a59", 1},
    63      {"-0xf33e5a5a59", 0},
    64      { "0xed1b1182118135d", 1},
    65      {"-0xed1b1182118135d", 1},
    66      { "0xe71f6eb7689cc276b2f1", 1},
    67      {"-0xe71f6eb7689cc276b2f1", 0},
    68      { "0x12644507fe78cf563a4b342c92e7da9fe5e99cb75a01", 1},
    69      {"-0x12644507fe78cf563a4b342c92e7da9fe5e99cb75a01", 0},
    70      { "0x1ff2e7c581bb0951df644885bd33f50e472b0b73a204e13cbe98fdb424d66561e4000000", 1},
    71      {"-0x1ff2e7c581bb0951df644885bd33f50e472b0b73a204e13cbe98fdb424d66561e4000000", 1},
    72      { "0x2b9b44db2d91a6f8165c8c7339ef73633228ea29e388592e80354e4380004aad84000000", 1},
    73      {"-0x2b9b44db2d91a6f8165c8c7339ef73633228ea29e388592e80354e4380004aad84000000", 1},
    74      { "0x28d5a2b8f330910a9d3cda06036ae0546442e5b1a83b26a436efea5b727bf1bcbe7e12b47d81", 1},
    75      {"-0x28d5a2b8f330910a9d3cda06036ae0546442e5b1a83b26a436efea5b727bf1bcbe7e12b47d81", 1},
    76      {NULL, 0}
    77    };
    78  
    79  
    80  void
    81  check_tests ()
    82  {
    83    mpz_t x;
    84    int i;
    85    int got, want;
    86  
    87    mpz_init (x);
    88  
    89    for (i = 0; tests[i].num_as_str != NULL; i++)
    90      {
    91        mpz_set_str (x, tests[i].num_as_str, 0);
    92        got = mpz_perfect_power_p (x);
    93        want = tests[i].want;
    94        if (got != want)
    95  	{
    96  	  fprintf (stderr, "mpz_perfect_power_p returns %d when %d was expected\n", got, want);
    97  	  fprintf (stderr, "fault operand: %s\n", tests[i].num_as_str);
    98  	  abort ();
    99  	}
   100      }
   101  
   102    mpz_clear (x);
   103  }
   104  
   105  #define NRP 15
   106  
   107  void
   108  check_random (int reps)
   109  {
   110    mpz_t n, np, temp, primes[NRP];
   111    int i, j, k, unique, destroy, res;
   112    unsigned long int nrprimes, primebits;
   113    mp_limb_t g, exp[NRP], e;
   114    gmp_randstate_ptr rands;
   115  
   116    rands = RANDS;
   117  
   118    mpz_init (n);
   119    mpz_init (np);
   120    mpz_init (temp);
   121  
   122    for (i = 0; i < NRP; i++)
   123      mpz_init (primes[i]);
   124  
   125    for (i = 0; i < reps; i++)
   126      {
   127        mpz_urandomb (np, rands, 32);
   128        nrprimes = mpz_get_ui (np) % NRP + 1; /* 1-NRP unique primes */
   129  
   130        mpz_urandomb (np, rands, 32);
   131        g = mpz_get_ui (np) % 32 + 2; /* gcd 2-33 */
   132  
   133        for (j = 0; j < nrprimes;)
   134  	{
   135  	  mpz_urandomb (np, rands, 32);
   136  	  primebits = mpz_get_ui (np) % 100 + 3; /* 3-102 bit primes */
   137  	  mpz_urandomb (primes[j], rands, primebits);
   138  	  mpz_nextprime (primes[j], primes[j]);
   139  	  unique = 1;
   140  	  for (k = 0; k < j; k++)
   141  	    {
   142  	      if (mpz_cmp (primes[j], primes[k]) == 0)
   143  		{
   144  		  unique = 0;
   145  		  break;
   146  		}
   147  	    }
   148  	  if (unique)
   149  	    {
   150  	      mpz_urandomb (np, rands, 32);
   151  	      e = 371 / (10 * primebits) + mpz_get_ui (np) % 11 + 1; /* Magic constants */
   152  	      exp[j++] = g * e;
   153  	    }
   154  	}
   155  
   156        if (nrprimes > 1)
   157  	{
   158  	  /* Destroy d exponents, d in [1, nrprimes - 1] */
   159  	  if (nrprimes == 2)
   160  	    {
   161  	      destroy = 1;
   162  	    }
   163  	  else
   164  	    {
   165  	      mpz_urandomb (np, rands, 32);
   166  	      destroy = mpz_get_ui (np) % (nrprimes - 2);
   167  	    }
   168  
   169  	  g = exp[destroy];
   170  	  for (k = destroy + 1; k < nrprimes; k++)
   171  	    g = mpn_gcd_1 (&g, 1, exp[k]);
   172  
   173  	  for (j = 0; j < destroy; j++)
   174  	    {
   175  	      mpz_urandomb (np, rands, 32);
   176  	      e = mpz_get_ui (np) % 50 + 1;
   177  	      while (mpn_gcd_1 (&g, 1, e) > 1)
   178  		e++;
   179  
   180  	      exp[j] = e;
   181  	    }
   182  	}
   183  
   184        /* Compute n */
   185        mpz_pow_ui (n, primes[0], exp[0]);
   186        for (j = 1; j < nrprimes; j++)
   187  	{
   188  	  mpz_pow_ui (temp, primes[j], exp[j]);
   189  	  mpz_mul (n, n, temp);
   190  	}
   191  
   192        res = mpz_perfect_power_p (n);
   193  
   194        if (nrprimes == 1)
   195  	{
   196  	if (res == 0 && exp[0] > 1)
   197  	  {
   198  	    printf("n is a perfect power, perfpow_p disagrees\n");
   199  	    gmp_printf("n = %Zu\nprimes[0] = %Zu\nexp[0] = %lu\n", n, primes[0], exp[0]);
   200  	    abort ();
   201  	  }
   202  	else if (res == 1 && exp[0] == 1)
   203  	  {
   204  	    gmp_printf("n = %Zu\n", n);
   205  	    printf("n is now a prime number, but perfpow_p still believes n is a perfect power\n");
   206  	    abort ();
   207  	  }
   208  	}
   209        else
   210  	{
   211  	  if (res == 1 && destroy != 0)
   212  	    {
   213  	      gmp_printf("n = %Zu\nn was destroyed, but perfpow_p still believes n is a perfect power\n", n);
   214  	      abort ();
   215  	    }
   216  	  else if (res == 0 && destroy == 0)
   217  	    {
   218  	      gmp_printf("n = %Zu\nn is a perfect power, perfpow_p disagrees\n", n);
   219  	      abort ();
   220  	    }
   221  	}
   222      }
   223  
   224    mpz_clear (n);
   225    mpz_clear (np);
   226    mpz_clear (temp);
   227    for (i = 0; i < NRP; i++)
   228      mpz_clear (primes[i]);
   229  }
   230  
   231  int
   232  main (int argc, char **argv)
   233  {
   234    int n_tests;
   235  
   236    tests_start ();
   237    mp_trace_base = -16;
   238  
   239    check_tests ();
   240  
   241    n_tests = 500;
   242    if (argc == 2)
   243      n_tests = atoi (argv[1]);
   244    check_random (n_tests);
   245  
   246    tests_end ();
   247    exit (0);
   248  }