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