Home | History | Annotate | Line # | Download | only in mpz
      1      1.1  mrg /* Test mpz_root, mpz_rootrem, and mpz_perfect_power_p.
      2      1.1  mrg 
      3  1.1.1.3  mrg Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2009, 2015 Free Software
      4  1.1.1.3  mrg Foundation, Inc.
      5      1.1  mrg 
      6  1.1.1.2  mrg This file is part of the GNU MP Library test suite.
      7      1.1  mrg 
      8  1.1.1.2  mrg The GNU MP Library test suite is free software; you can redistribute it
      9  1.1.1.2  mrg and/or modify it under the terms of the GNU General Public License as
     10  1.1.1.2  mrg published by the Free Software Foundation; either version 3 of the License,
     11  1.1.1.2  mrg or (at your option) any later version.
     12  1.1.1.2  mrg 
     13  1.1.1.2  mrg The GNU MP Library test suite is distributed in the hope that it will be
     14  1.1.1.2  mrg useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1.1.2  mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     16  1.1.1.2  mrg Public License for more details.
     17      1.1  mrg 
     18  1.1.1.2  mrg You should have received a copy of the GNU General Public License along with
     19  1.1.1.3  mrg the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
     20      1.1  mrg 
     21      1.1  mrg #include <stdio.h>
     22      1.1  mrg #include <stdlib.h>
     23      1.1  mrg 
     24      1.1  mrg #include "gmp-impl.h"
     25      1.1  mrg #include "tests.h"
     26      1.1  mrg 
     27  1.1.1.2  mrg void debug_mp (mpz_t, int);
     28      1.1  mrg 
     29      1.1  mrg void
     30  1.1.1.3  mrg check_one (mpz_t root1, mpz_t x2, unsigned long nth, int res, int i)
     31      1.1  mrg {
     32      1.1  mrg   mpz_t temp, temp2;
     33      1.1  mrg   mpz_t root2, rem2;
     34      1.1  mrg 
     35      1.1  mrg   mpz_init (root2);
     36      1.1  mrg   mpz_init (rem2);
     37      1.1  mrg   mpz_init (temp);
     38      1.1  mrg   mpz_init (temp2);
     39      1.1  mrg 
     40      1.1  mrg   MPZ_CHECK_FORMAT (root1);
     41      1.1  mrg 
     42      1.1  mrg   mpz_rootrem (root2, rem2, x2, nth);
     43      1.1  mrg   MPZ_CHECK_FORMAT (root2);
     44      1.1  mrg   MPZ_CHECK_FORMAT (rem2);
     45      1.1  mrg 
     46      1.1  mrg   mpz_pow_ui (temp, root1, nth);
     47      1.1  mrg   MPZ_CHECK_FORMAT (temp);
     48      1.1  mrg 
     49      1.1  mrg   mpz_add (temp2, temp, rem2);
     50      1.1  mrg 
     51      1.1  mrg   /* Is power of result > argument?  */
     52  1.1.1.3  mrg   if (mpz_cmp (root1, root2) != 0 || mpz_cmp (x2, temp2) != 0 || mpz_cmpabs (temp, x2) > 0 || res == mpz_cmp_ui (rem2, 0))
     53      1.1  mrg     {
     54      1.1  mrg       fprintf (stderr, "ERROR after test %d\n", i);
     55      1.1  mrg       debug_mp (x2, 10);
     56      1.1  mrg       debug_mp (root1, 10);
     57      1.1  mrg       debug_mp (root2, 10);
     58  1.1.1.3  mrg       fprintf (stderr, "nth: %lu ,res: %i\n", nth, res);
     59      1.1  mrg       abort ();
     60      1.1  mrg     }
     61      1.1  mrg 
     62      1.1  mrg   if (nth > 1 && mpz_cmp_ui (temp, 1L) > 0 && ! mpz_perfect_power_p (temp))
     63      1.1  mrg     {
     64      1.1  mrg       fprintf (stderr, "ERROR in mpz_perfect_power_p after test %d\n", i);
     65      1.1  mrg       debug_mp (temp, 10);
     66      1.1  mrg       debug_mp (root1, 10);
     67      1.1  mrg       fprintf (stderr, "nth: %lu\n", nth);
     68      1.1  mrg       abort ();
     69      1.1  mrg     }
     70      1.1  mrg 
     71  1.1.1.2  mrg   if (nth <= 10000 && mpz_sgn(x2) > 0)		/* skip too expensive test */
     72      1.1  mrg     {
     73      1.1  mrg       mpz_add_ui (temp2, root1, 1L);
     74      1.1  mrg       mpz_pow_ui (temp2, temp2, nth);
     75      1.1  mrg       MPZ_CHECK_FORMAT (temp2);
     76      1.1  mrg 
     77      1.1  mrg       /* Is square of (result + 1) <= argument?  */
     78      1.1  mrg       if (mpz_cmp (temp2, x2) <= 0)
     79      1.1  mrg 	{
     80      1.1  mrg 	  fprintf (stderr, "ERROR after test %d\n", i);
     81      1.1  mrg 	  debug_mp (x2, 10);
     82      1.1  mrg 	  debug_mp (root1, 10);
     83      1.1  mrg 	  fprintf (stderr, "nth: %lu\n", nth);
     84      1.1  mrg 	  abort ();
     85      1.1  mrg 	}
     86      1.1  mrg     }
     87      1.1  mrg 
     88      1.1  mrg   mpz_clear (root2);
     89      1.1  mrg   mpz_clear (rem2);
     90      1.1  mrg   mpz_clear (temp);
     91      1.1  mrg   mpz_clear (temp2);
     92      1.1  mrg }
     93      1.1  mrg 
     94      1.1  mrg int
     95      1.1  mrg main (int argc, char **argv)
     96      1.1  mrg {
     97      1.1  mrg   mpz_t x2;
     98      1.1  mrg   mpz_t root1;
     99      1.1  mrg   mp_size_t x2_size;
    100  1.1.1.3  mrg   int i, res;
    101      1.1  mrg   int reps = 500;
    102      1.1  mrg   unsigned long nth;
    103      1.1  mrg   gmp_randstate_ptr rands;
    104      1.1  mrg   mpz_t bs;
    105      1.1  mrg   unsigned long bsi, size_range;
    106      1.1  mrg 
    107      1.1  mrg   tests_start ();
    108      1.1  mrg   TESTS_REPS (reps, argv, argc);
    109      1.1  mrg 
    110      1.1  mrg   rands = RANDS;
    111      1.1  mrg 
    112      1.1  mrg   mpz_init (bs);
    113      1.1  mrg 
    114      1.1  mrg   mpz_init (x2);
    115      1.1  mrg   mpz_init (root1);
    116      1.1  mrg 
    117      1.1  mrg   /* This triggers a gcc 4.3.2 bug */
    118      1.1  mrg   mpz_set_str (x2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16);
    119  1.1.1.3  mrg   res = mpz_root (root1, x2, 2);
    120  1.1.1.3  mrg   check_one (root1, x2, 2, res, -1);
    121      1.1  mrg 
    122      1.1  mrg   for (i = 0; i < reps; i++)
    123      1.1  mrg     {
    124      1.1  mrg       mpz_urandomb (bs, rands, 32);
    125      1.1  mrg       size_range = mpz_get_ui (bs) % 17 + 2;
    126      1.1  mrg 
    127      1.1  mrg       mpz_urandomb (bs, rands, size_range);
    128      1.1  mrg       x2_size = mpz_get_ui (bs) + 10;
    129      1.1  mrg       mpz_rrandomb (x2, rands, x2_size);
    130      1.1  mrg 
    131      1.1  mrg       mpz_urandomb (bs, rands, 15);
    132      1.1  mrg       nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2;
    133      1.1  mrg 
    134  1.1.1.3  mrg       res = mpz_root (root1, x2, nth);
    135      1.1  mrg 
    136      1.1  mrg       mpz_urandomb (bs, rands, 4);
    137      1.1  mrg       bsi = mpz_get_ui (bs);
    138      1.1  mrg       if ((bsi & 1) != 0)
    139      1.1  mrg 	{
    140      1.1  mrg 	  /* With 50% probability, set x2 near a perfect power.  */
    141      1.1  mrg 	  mpz_pow_ui (x2, root1, nth);
    142      1.1  mrg 	  if ((bsi & 2) != 0)
    143      1.1  mrg 	    {
    144      1.1  mrg 	      mpz_sub_ui (x2, x2, bsi >> 2);
    145      1.1  mrg 	      mpz_abs (x2, x2);
    146      1.1  mrg 	    }
    147      1.1  mrg 	  else
    148      1.1  mrg 	    mpz_add_ui (x2, x2, bsi >> 2);
    149  1.1.1.3  mrg 	  res = mpz_root (root1, x2, nth);
    150      1.1  mrg 	}
    151      1.1  mrg 
    152  1.1.1.3  mrg       check_one (root1, x2, nth, res, i);
    153  1.1.1.2  mrg 
    154  1.1.1.2  mrg       if (((nth & 1) != 0) && ((bsi & 2) != 0))
    155  1.1.1.2  mrg 	{
    156  1.1.1.2  mrg 	  mpz_neg (x2, x2);
    157  1.1.1.2  mrg 	  mpz_neg (root1, root1);
    158  1.1.1.3  mrg 	  check_one (root1, x2, nth, res, i);
    159  1.1.1.2  mrg 	}
    160      1.1  mrg     }
    161      1.1  mrg 
    162      1.1  mrg   mpz_clear (bs);
    163      1.1  mrg   mpz_clear (x2);
    164      1.1  mrg   mpz_clear (root1);
    165      1.1  mrg 
    166      1.1  mrg   tests_end ();
    167      1.1  mrg   exit (0);
    168      1.1  mrg }
    169      1.1  mrg 
    170      1.1  mrg void
    171      1.1  mrg debug_mp (mpz_t x, int base)
    172      1.1  mrg {
    173      1.1  mrg   mpz_out_str (stderr, base, x); fputc ('\n', stderr);
    174      1.1  mrg }
    175