(root)/
gmp-6.3.0/
tests/
mpz/
t-powm_ui.c
       1  /* Test mpz_powm_ui, mpz_mul, mpz_mod.
       2  
       3  Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2013 Free Software
       4  Foundation, Inc.
       5  
       6  This file is part of the GNU MP Library test suite.
       7  
       8  The GNU MP Library test suite is free software; you can redistribute it
       9  and/or modify it under the terms of the GNU General Public License as
      10  published by the Free Software Foundation; either version 3 of the License,
      11  or (at your option) any later version.
      12  
      13  The GNU MP Library test suite is distributed in the hope that it will be
      14  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
      15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
      16  Public License for more details.
      17  
      18  You should have received a copy of the GNU General Public License along with
      19  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
      20  
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  
      24  #include "gmp-impl.h"
      25  #include "tests.h"
      26  
      27  int
      28  main (int argc, char **argv)
      29  {
      30    mpz_t base, exp, mod;
      31    mpz_t r1, r2, base2;
      32    mp_size_t base_size, exp_size, mod_size;
      33    unsigned long int exp2;
      34    int i;
      35    int reps = 100;
      36    gmp_randstate_ptr rands;
      37    mpz_t bs;
      38    unsigned long bsi, size_range;
      39  
      40    tests_start ();
      41    rands = RANDS;
      42  
      43    TESTS_REPS (reps, argv, argc);
      44  
      45    mpz_inits (bs, base, exp, mod, r1, r2, base2, NULL);
      46  
      47    for (i = 0; i < reps; i++)
      48      {
      49        mpz_urandomb (bs, rands, 32);
      50        size_range = mpz_get_ui (bs) % 18 + 2;
      51  
      52        do  /* Loop until mathematically well-defined.  */
      53  	{
      54  	  mpz_urandomb (bs, rands, size_range);
      55  	  base_size = mpz_get_ui (bs);
      56  	  mpz_rrandomb (base, rands, base_size);
      57  
      58  	  mpz_urandomb (bs, rands, 6L);
      59  	  exp_size = mpz_get_ui (bs);
      60  	  mpz_rrandomb (exp, rands, exp_size);
      61  	  exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
      62  	}
      63        while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);
      64  
      65        do
      66          {
      67  	  mpz_urandomb (bs, rands, size_range);
      68  	  mod_size = mpz_get_ui (bs);
      69  	  mpz_rrandomb (mod, rands, mod_size);
      70  	}
      71        while (mpz_cmp_ui (mod, 0) == 0);
      72  
      73        mpz_urandomb (bs, rands, 2);
      74        bsi = mpz_get_ui (bs);
      75        if ((bsi & 1) != 0)
      76  	mpz_neg (base, base);
      77  
      78        /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */
      79  
      80  #if 0
      81        putc ('\n', stderr);
      82        gmp_fprintf (stderr, "B = 0x%Zx\n", base);
      83        gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
      84  #endif
      85  
      86        exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
      87        mpz_set_ui (r2, 1);
      88        mpz_set (base2, base);
      89        mpz_mod (r2, r2, mod);	/* needed when exp==0 and mod==1 */
      90        while (exp2 != 0)
      91  	{
      92  	  if (exp2 % 2 != 0)
      93  	    {
      94  	      mpz_mul (r2, r2, base2);
      95  	      mpz_mod (r2, r2, mod);
      96  	    }
      97  	  mpz_mul (base2, base2, base2);
      98  	  mpz_mod (base2, base2, mod);
      99  	  exp2 = exp2 / 2;
     100  	}
     101  
     102        exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
     103        mpz_powm_ui (r1, base, exp2, mod);
     104        MPZ_CHECK_FORMAT (r1);
     105  
     106  #if 0
     107        gmp_fprintf (stderr, "R   = 0x%Zx\n", r1);
     108        gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
     109  #endif
     110  
     111        if (mpz_cmp (r1, r2) != 0)
     112  	{
     113  	  fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
     114  	  gmp_fprintf (stderr, "B = 0x%Zx\n", base);
     115  	  gmp_fprintf (stderr, "E = 0x%Zx\n", exp);
     116  	  gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
     117  	  gmp_fprintf (stderr, "R   = 0x%Zx\n", r1);
     118  	  gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
     119  	  abort ();
     120  	}
     121      }
     122  
     123    mpz_clears (bs, base, exp, mod, r1, r2, base2, NULL);
     124  
     125    tests_end ();
     126    exit (0);
     127  }