github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-root.c (about) 1 /* Test mpz_root, mpz_rootrem, and mpz_perfect_power_p. 2 3 Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2009, 2015 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.h" 25 #include "gmp-impl.h" 26 #include "tests.h" 27 28 void debug_mp (mpz_t, int); 29 30 void 31 check_one (mpz_t root1, mpz_t x2, unsigned long nth, int res, int i) 32 { 33 mpz_t temp, temp2; 34 mpz_t root2, rem2; 35 36 mpz_init (root2); 37 mpz_init (rem2); 38 mpz_init (temp); 39 mpz_init (temp2); 40 41 MPZ_CHECK_FORMAT (root1); 42 43 mpz_rootrem (root2, rem2, x2, nth); 44 MPZ_CHECK_FORMAT (root2); 45 MPZ_CHECK_FORMAT (rem2); 46 47 mpz_pow_ui (temp, root1, nth); 48 MPZ_CHECK_FORMAT (temp); 49 50 mpz_add (temp2, temp, rem2); 51 52 /* Is power of result > argument? */ 53 if (mpz_cmp (root1, root2) != 0 || mpz_cmp (x2, temp2) != 0 || mpz_cmpabs (temp, x2) > 0 || res == mpz_cmp_ui (rem2, 0)) 54 { 55 fprintf (stderr, "ERROR after test %d\n", i); 56 debug_mp (x2, 10); 57 debug_mp (root1, 10); 58 debug_mp (root2, 10); 59 fprintf (stderr, "nth: %lu ,res: %i\n", nth, res); 60 abort (); 61 } 62 63 if (nth > 1 && mpz_cmp_ui (temp, 1L) > 0 && ! mpz_perfect_power_p (temp)) 64 { 65 fprintf (stderr, "ERROR in mpz_perfect_power_p after test %d\n", i); 66 debug_mp (temp, 10); 67 debug_mp (root1, 10); 68 fprintf (stderr, "nth: %lu\n", nth); 69 abort (); 70 } 71 72 if (nth <= 10000 && mpz_sgn(x2) > 0) /* skip too expensive test */ 73 { 74 mpz_add_ui (temp2, root1, 1L); 75 mpz_pow_ui (temp2, temp2, nth); 76 MPZ_CHECK_FORMAT (temp2); 77 78 /* Is square of (result + 1) <= argument? */ 79 if (mpz_cmp (temp2, x2) <= 0) 80 { 81 fprintf (stderr, "ERROR after test %d\n", i); 82 debug_mp (x2, 10); 83 debug_mp (root1, 10); 84 fprintf (stderr, "nth: %lu\n", nth); 85 abort (); 86 } 87 } 88 89 mpz_clear (root2); 90 mpz_clear (rem2); 91 mpz_clear (temp); 92 mpz_clear (temp2); 93 } 94 95 int 96 main (int argc, char **argv) 97 { 98 mpz_t x2; 99 mpz_t root1; 100 mp_size_t x2_size; 101 int i, res; 102 int reps = 500; 103 unsigned long nth; 104 gmp_randstate_ptr rands; 105 mpz_t bs; 106 unsigned long bsi, size_range; 107 108 tests_start (); 109 TESTS_REPS (reps, argv, argc); 110 111 rands = RANDS; 112 113 mpz_init (bs); 114 115 mpz_init (x2); 116 mpz_init (root1); 117 118 /* This triggers a gcc 4.3.2 bug */ 119 mpz_set_str (x2, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000002", 16); 120 res = mpz_root (root1, x2, 2); 121 check_one (root1, x2, 2, res, -1); 122 123 for (i = 0; i < reps; i++) 124 { 125 mpz_urandomb (bs, rands, 32); 126 size_range = mpz_get_ui (bs) % 17 + 2; 127 128 mpz_urandomb (bs, rands, size_range); 129 x2_size = mpz_get_ui (bs) + 10; 130 mpz_rrandomb (x2, rands, x2_size); 131 132 mpz_urandomb (bs, rands, 15); 133 nth = mpz_getlimbn (bs, 0) % mpz_sizeinbase (x2, 2) + 2; 134 135 res = mpz_root (root1, x2, nth); 136 137 mpz_urandomb (bs, rands, 4); 138 bsi = mpz_get_ui (bs); 139 if ((bsi & 1) != 0) 140 { 141 /* With 50% probability, set x2 near a perfect power. */ 142 mpz_pow_ui (x2, root1, nth); 143 if ((bsi & 2) != 0) 144 { 145 mpz_sub_ui (x2, x2, bsi >> 2); 146 mpz_abs (x2, x2); 147 } 148 else 149 mpz_add_ui (x2, x2, bsi >> 2); 150 res = mpz_root (root1, x2, nth); 151 } 152 153 check_one (root1, x2, nth, res, i); 154 155 if (((nth & 1) != 0) && ((bsi & 2) != 0)) 156 { 157 mpz_neg (x2, x2); 158 mpz_neg (root1, root1); 159 check_one (root1, x2, nth, res, i); 160 } 161 } 162 163 mpz_clear (bs); 164 mpz_clear (x2); 165 mpz_clear (root1); 166 167 tests_end (); 168 exit (0); 169 } 170 171 void 172 debug_mp (mpz_t x, int base) 173 { 174 mpz_out_str (stderr, base, x); fputc ('\n', stderr); 175 }