github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-pow.c (about) 1 /* Test mpz_pow_ui and mpz_ui_pow_ui. 2 3 Copyright 1997, 1999-2001 Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 23 #include "gmp.h" 24 #include "gmp-impl.h" 25 #include "tests.h" 26 27 28 void 29 check_one (mpz_srcptr want, mpz_srcptr base, unsigned long exp) 30 { 31 mpz_t got; 32 33 mpz_init (got); 34 35 MPZ_CHECK_FORMAT (want); 36 37 mpz_pow_ui (got, base, exp); 38 if (mpz_cmp (got, want)) 39 { 40 printf ("mpz_pow_ui wrong\n"); 41 mpz_trace (" base", base); 42 printf (" exp = %lu (0x%lX)\n", exp, exp); 43 mpz_trace (" got ", got); 44 mpz_trace (" want", want); 45 abort (); 46 } 47 48 mpz_set (got, base); 49 mpz_pow_ui (got, got, exp); 50 if (mpz_cmp (got, want)) 51 { 52 printf ("mpz_pow_ui wrong\n"); 53 mpz_trace (" base", base); 54 printf (" exp = %lu (0x%lX)\n", exp, exp); 55 mpz_trace (" got ", got); 56 mpz_trace (" want", want); 57 abort (); 58 } 59 60 if (mpz_fits_ulong_p (base)) 61 { 62 unsigned long base_u = mpz_get_ui (base); 63 mpz_ui_pow_ui (got, base_u, exp); 64 if (mpz_cmp (got, want)) 65 { 66 printf ("mpz_ui_pow_ui wrong\n"); 67 printf (" base=%lu (0x%lX)\n", base_u, base_u); 68 printf (" exp = %lu (0x%lX)\n", exp, exp); 69 mpz_trace (" got ", got); 70 mpz_trace (" want", want); 71 abort (); 72 } 73 } 74 75 mpz_clear (got); 76 } 77 78 void 79 check_base (mpz_srcptr base) 80 { 81 unsigned long exp; 82 mpz_t want; 83 84 mpz_init (want); 85 mpz_set_ui (want, 1L); 86 87 for (exp = 0; exp < 20; exp++) 88 { 89 check_one (want, base, exp); 90 mpz_mul (want, want, base); 91 } 92 93 mpz_clear (want); 94 } 95 96 void 97 check_various (void) 98 { 99 static const struct { 100 const char *base; 101 } data[] = { 102 { "0" }, 103 { "1" }, 104 { "2" }, 105 { "3" }, 106 { "4" }, 107 { "5" }, 108 { "6" }, 109 { "10" }, 110 { "15" }, 111 { "16" }, 112 113 { "0x1F" }, 114 { "0xFF" }, 115 { "0x1001" }, 116 { "0xFFFF" }, 117 { "0x10000001" }, 118 { "0x1000000000000001" }, 119 120 /* actual size closest to estimate */ 121 { "0xFFFFFFFF" }, 122 { "0xFFFFFFFFFFFFFFFF" }, 123 124 /* same after rshift */ 125 { "0xFFFFFFFF0" }, 126 { "0xFFFFFFFF00" }, 127 { "0xFFFFFFFFFFFFFFFF0" }, 128 { "0xFFFFFFFFFFFFFFFF00" }, 129 130 /* change from 2 limbs to 1 after rshift */ 131 { "0x180000000" }, 132 { "0x18000000000000000" }, 133 134 /* change from 3 limbs to 2 after rshift */ 135 { "0x18000000100000000" }, 136 { "0x180000000000000010000000000000000" }, 137 138 /* handling of absolute value */ 139 { "-0x80000000" }, 140 { "-0x8000000000000000" }, 141 142 /* low zero limb, and size>2, checking argument overlap detection */ 143 { "0x3000000000000000300000000000000030000000000000000" }, 144 }; 145 146 mpz_t base; 147 int i; 148 149 mpz_init (base); 150 151 for (i = 0; i < numberof (data); i++) 152 { 153 mpz_set_str_or_abort (base, data[i].base, 0); 154 check_base (base); 155 } 156 157 mpz_clear (base); 158 } 159 160 void 161 check_random (int reps) 162 { 163 mpz_t base, want; 164 mp_size_t base_size; 165 int i; 166 unsigned long size_range, exp; 167 gmp_randstate_ptr rands = RANDS; 168 169 mpz_init (base); 170 mpz_init (want); 171 172 for (i = 0; i < reps; i++) 173 { 174 /* exponentially random 0 to 2^13 bits for base */ 175 mpz_urandomb (want, rands, 32); 176 size_range = mpz_get_ui (want) % 12 + 2; 177 mpz_urandomb (want, rands, size_range); 178 base_size = mpz_get_ui (want); 179 mpz_rrandomb (base, rands, base_size); 180 181 /* randomly signed base */ 182 mpz_urandomb (want, rands, 2); 183 if ((mpz_get_ui (want) & 1) != 0) 184 mpz_neg (base, base); 185 186 /* random 5 bits for exponent */ 187 mpz_urandomb (want, rands, 5L); 188 exp = mpz_get_ui (want); 189 190 refmpz_pow_ui (want, base, exp); 191 check_one (want, base, exp); 192 } 193 194 mpz_clear (base); 195 mpz_clear (want); 196 } 197 198 int 199 main (int argc, char **argv) 200 { 201 int reps = 5000; 202 203 /* dummy call to drag in refmpn.o for testing mpz/n_pow_ui.c with 204 refmpn_mul_2 */ 205 refmpn_zero_p (NULL, (mp_size_t) 0); 206 207 tests_start (); 208 mp_trace_base = -16; 209 210 if (argc == 2) 211 reps = atoi (argv[1]); 212 213 check_various (); 214 check_random (reps); 215 216 tests_end (); 217 exit (0); 218 }