github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpq/t-md_2exp.c (about) 1 /* Test mpq_mul_2exp and mpq_div_2exp. 2 3 Copyright 2000, 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 #include "gmp.h" 23 #include "gmp-impl.h" 24 #include "tests.h" 25 26 27 struct pair_t { 28 const char *num; 29 const char *den; 30 }; 31 32 void 33 check_random () 34 { 35 gmp_randstate_ptr rands; 36 mpz_t bs; 37 unsigned long arg_size, size_range; 38 mpq_t q, r; 39 int i; 40 mp_bitcnt_t shift; 41 int reps = 10000; 42 43 rands = RANDS; 44 45 mpz_init (bs); 46 mpq_init (q); 47 mpq_init (r); 48 49 for (i = 0; i < reps; i++) 50 { 51 mpz_urandomb (bs, rands, 32); 52 size_range = mpz_get_ui (bs) % 11 + 2; /* 0..4096 bit operands */ 53 54 mpz_urandomb (bs, rands, size_range); 55 arg_size = mpz_get_ui (bs); 56 mpz_rrandomb (mpq_numref (q), rands, arg_size); 57 do 58 { 59 mpz_urandomb (bs, rands, size_range); 60 arg_size = mpz_get_ui (bs); 61 mpz_rrandomb (mpq_denref (q), rands, arg_size); 62 } 63 while (mpz_sgn (mpq_denref (q)) == 0); 64 65 /* We now have a random rational in q, albeit an unnormalised one. The 66 lack of normalisation should not matter here, so let's save the time a 67 gcd would require. */ 68 69 mpz_urandomb (bs, rands, 32); 70 shift = mpz_get_ui (bs) % 4096; 71 72 mpq_mul_2exp (r, q, shift); 73 74 if (mpq_cmp (r, q) < 0) 75 { 76 printf ("mpq_mul_2exp wrong on random\n"); 77 abort (); 78 } 79 80 mpq_div_2exp (r, r, shift); 81 82 if (mpq_cmp (r, q) != 0) 83 { 84 printf ("mpq_mul_2exp or mpq_div_2exp wrong on random\n"); 85 abort (); 86 } 87 } 88 mpq_clear (q); 89 mpq_clear (r); 90 mpz_clear (bs); 91 } 92 93 int 94 main (int argc, char **argv) 95 { 96 static const struct { 97 struct pair_t left; 98 unsigned long n; 99 struct pair_t right; 100 101 } data[] = { 102 { {"0","1"}, 0, {"0","1"} }, 103 { {"0","1"}, 1, {"0","1"} }, 104 { {"0","1"}, 2, {"0","1"} }, 105 106 { {"1","1"}, 0, {"1","1"} }, 107 { {"1","1"}, 1, {"2","1"} }, 108 { {"1","1"}, 2, {"4","1"} }, 109 { {"1","1"}, 3, {"8","1"} }, 110 111 { {"1","1"}, 31, {"0x80000000","1"} }, 112 { {"1","1"}, 32, {"0x100000000","1"} }, 113 { {"1","1"}, 33, {"0x200000000","1"} }, 114 { {"1","1"}, 63, {"0x8000000000000000","1"} }, 115 { {"1","1"}, 64, {"0x10000000000000000","1"} }, 116 { {"1","1"}, 65, {"0x20000000000000000","1"} }, 117 { {"1","1"}, 95, {"0x800000000000000000000000","1"} }, 118 { {"1","1"}, 96, {"0x1000000000000000000000000","1"} }, 119 { {"1","1"}, 97, {"0x2000000000000000000000000","1"} }, 120 { {"1","1"}, 127, {"0x80000000000000000000000000000000","1"} }, 121 { {"1","1"}, 128, {"0x100000000000000000000000000000000","1"} }, 122 { {"1","1"}, 129, {"0x200000000000000000000000000000000","1"} }, 123 124 { {"1","2"}, 31, {"0x40000000","1"} }, 125 { {"1","2"}, 32, {"0x80000000","1"} }, 126 { {"1","2"}, 33, {"0x100000000","1"} }, 127 { {"1","2"}, 63, {"0x4000000000000000","1"} }, 128 { {"1","2"}, 64, {"0x8000000000000000","1"} }, 129 { {"1","2"}, 65, {"0x10000000000000000","1"} }, 130 { {"1","2"}, 95, {"0x400000000000000000000000","1"} }, 131 { {"1","2"}, 96, {"0x800000000000000000000000","1"} }, 132 { {"1","2"}, 97, {"0x1000000000000000000000000","1"} }, 133 { {"1","2"}, 127, {"0x40000000000000000000000000000000","1"} }, 134 { {"1","2"}, 128, {"0x80000000000000000000000000000000","1"} }, 135 { {"1","2"}, 129, {"0x100000000000000000000000000000000","1"} }, 136 137 { {"1","0x80000000"}, 30, {"1","2"} }, 138 { {"1","0x80000000"}, 31, {"1","1"} }, 139 { {"1","0x80000000"}, 32, {"2","1"} }, 140 { {"1","0x80000000"}, 33, {"4","1"} }, 141 { {"1","0x80000000"}, 62, {"0x80000000","1"} }, 142 { {"1","0x80000000"}, 63, {"0x100000000","1"} }, 143 { {"1","0x80000000"}, 64, {"0x200000000","1"} }, 144 { {"1","0x80000000"}, 94, {"0x8000000000000000","1"} }, 145 { {"1","0x80000000"}, 95, {"0x10000000000000000","1"} }, 146 { {"1","0x80000000"}, 96, {"0x20000000000000000","1"} }, 147 { {"1","0x80000000"}, 126, {"0x800000000000000000000000","1"} }, 148 { {"1","0x80000000"}, 127, {"0x1000000000000000000000000","1"} }, 149 { {"1","0x80000000"}, 128, {"0x2000000000000000000000000","1"} }, 150 151 { {"1","0x100000000"}, 1, {"1","0x80000000"} }, 152 { {"1","0x100000000"}, 2, {"1","0x40000000"} }, 153 { {"1","0x100000000"}, 3, {"1","0x20000000"} }, 154 155 { {"1","0x10000000000000000"}, 1, {"1","0x8000000000000000"} }, 156 { {"1","0x10000000000000000"}, 2, {"1","0x4000000000000000"} }, 157 { {"1","0x10000000000000000"}, 3, {"1","0x2000000000000000"} }, 158 }; 159 160 void (*fun) (mpq_ptr, mpq_srcptr, unsigned long); 161 const struct pair_t *p_start, *p_want; 162 const char *name; 163 mpq_t sep, got, want; 164 mpq_ptr q; 165 int i, muldiv, sign, overlap; 166 167 tests_start (); 168 169 mpq_init (sep); 170 mpq_init (got); 171 mpq_init (want); 172 173 for (i = 0; i < numberof (data); i++) 174 { 175 for (muldiv = 0; muldiv < 2; muldiv++) 176 { 177 if (muldiv == 0) 178 { 179 fun = mpq_mul_2exp; 180 name = "mpq_mul_2exp"; 181 p_start = &data[i].left; 182 p_want = &data[i].right; 183 } 184 else 185 { 186 fun = mpq_div_2exp; 187 name = "mpq_div_2exp"; 188 p_start = &data[i].right; 189 p_want = &data[i].left; 190 } 191 192 for (sign = 0; sign <= 1; sign++) 193 { 194 mpz_set_str_or_abort (mpq_numref(want), p_want->num, 0); 195 mpz_set_str_or_abort (mpq_denref(want), p_want->den, 0); 196 if (sign) 197 mpq_neg (want, want); 198 199 for (overlap = 0; overlap <= 1; overlap++) 200 { 201 q = overlap ? got : sep; 202 203 /* initial garbage in "got" */ 204 mpq_set_ui (got, 123L, 456L); 205 206 mpz_set_str_or_abort (mpq_numref(q), p_start->num, 0); 207 mpz_set_str_or_abort (mpq_denref(q), p_start->den, 0); 208 if (sign) 209 mpq_neg (q, q); 210 211 (*fun) (got, q, data[i].n); 212 MPQ_CHECK_FORMAT (got); 213 214 if (! mpq_equal (got, want)) 215 { 216 printf ("%s wrong at data[%d], sign %d, overlap %d\n", 217 name, i, sign, overlap); 218 printf (" num \"%s\"\n", p_start->num); 219 printf (" den \"%s\"\n", p_start->den); 220 printf (" n %lu\n", data[i].n); 221 222 printf (" got "); 223 mpq_out_str (stdout, 16, got); 224 printf (" (hex)\n"); 225 226 printf (" want "); 227 mpq_out_str (stdout, 16, want); 228 printf (" (hex)\n"); 229 230 abort (); 231 } 232 } 233 } 234 } 235 } 236 237 check_random (); 238 239 mpq_clear (sep); 240 mpq_clear (got); 241 mpq_clear (want); 242 243 tests_end (); 244 exit (0); 245 }