github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-aorsmul.c (about) 1 /* Test mpz_addmul, mpz_addmul_ui, mpz_submul, mpz_submul_ui. 2 3 Copyright 2001, 2002 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 21 #include <stdio.h> 22 #include <stdlib.h> 23 #include <string.h> 24 25 #include "gmp.h" 26 #include "gmp-impl.h" 27 #include "tests.h" 28 29 30 #define M GMP_NUMB_MAX 31 32 33 void 34 check_one_inplace (mpz_srcptr w, mpz_srcptr y) 35 { 36 mpz_t want, got; 37 38 mpz_init (want); 39 mpz_init (got); 40 41 mpz_mul (want, w, y); 42 mpz_add (want, w, want); 43 mpz_set (got, w); 44 mpz_addmul (got, got, y); 45 MPZ_CHECK_FORMAT (got); 46 if (mpz_cmp (want, got) != 0) 47 { 48 printf ("mpz_addmul inplace fail\n"); 49 fail: 50 mpz_trace ("w", w); 51 mpz_trace ("y", y); 52 mpz_trace ("want", want); 53 mpz_trace ("got ", got); 54 abort (); 55 } 56 57 mpz_mul (want, w, y); 58 mpz_sub (want, w, want); 59 mpz_set (got, w); 60 mpz_submul (got, got, y); 61 MPZ_CHECK_FORMAT (got); 62 if (mpz_cmp (want, got) != 0) 63 { 64 printf ("mpz_submul inplace fail\n"); 65 goto fail; 66 } 67 68 mpz_clear (want); 69 mpz_clear (got); 70 } 71 72 void 73 check_one_ui_inplace (mpz_ptr w, unsigned long y) 74 { 75 mpz_t want, got; 76 77 mpz_init (want); 78 mpz_init (got); 79 80 mpz_mul_ui (want, w, (unsigned long) y); 81 mpz_add (want, w, want); 82 mpz_set (got, w); 83 mpz_addmul_ui (got, got, (unsigned long) y); 84 MPZ_CHECK_FORMAT (got); 85 if (mpz_cmp (want, got) != 0) 86 { 87 printf ("mpz_addmul_ui fail\n"); 88 fail: 89 mpz_trace ("w", w); 90 printf ("y=0x%lX %lu\n", y, y); 91 mpz_trace ("want", want); 92 mpz_trace ("got ", got); 93 abort (); 94 } 95 96 mpz_mul_ui (want, w, y); 97 mpz_sub (want, w, want); 98 mpz_set (got, w); 99 mpz_submul_ui (got, got, y); 100 MPZ_CHECK_FORMAT (got); 101 if (mpz_cmp (want, got) != 0) 102 { 103 printf ("mpz_submul_ui fail\n"); 104 goto fail; 105 } 106 107 mpz_clear (want); 108 mpz_clear (got); 109 } 110 111 void 112 check_all_inplace (mpz_ptr w, mpz_ptr y) 113 { 114 int wneg, yneg; 115 116 MPZ_CHECK_FORMAT (w); 117 MPZ_CHECK_FORMAT (y); 118 119 for (wneg = 0; wneg < 2; wneg++) 120 { 121 for (yneg = 0; yneg < 2; yneg++) 122 { 123 check_one_inplace (w, y); 124 125 if (mpz_fits_ulong_p (y)) 126 check_one_ui_inplace (w, mpz_get_ui (y)); 127 128 mpz_neg (y, y); 129 } 130 mpz_neg (w, w); 131 } 132 } 133 134 void 135 check_one (mpz_srcptr w, mpz_srcptr x, mpz_srcptr y) 136 { 137 mpz_t want, got; 138 139 mpz_init (want); 140 mpz_init (got); 141 142 mpz_mul (want, x, y); 143 mpz_add (want, w, want); 144 mpz_set (got, w); 145 mpz_addmul (got, x, y); 146 MPZ_CHECK_FORMAT (got); 147 if (mpz_cmp (want, got) != 0) 148 { 149 printf ("mpz_addmul fail\n"); 150 fail: 151 mpz_trace ("w", w); 152 mpz_trace ("x", x); 153 mpz_trace ("y", y); 154 mpz_trace ("want", want); 155 mpz_trace ("got ", got); 156 abort (); 157 } 158 159 mpz_mul (want, x, y); 160 mpz_sub (want, w, want); 161 mpz_set (got, w); 162 mpz_submul (got, x, y); 163 MPZ_CHECK_FORMAT (got); 164 if (mpz_cmp (want, got) != 0) 165 { 166 printf ("mpz_submul fail\n"); 167 goto fail; 168 } 169 170 mpz_clear (want); 171 mpz_clear (got); 172 } 173 174 void 175 check_one_ui (mpz_ptr w, mpz_ptr x, unsigned long y) 176 { 177 mpz_t want, got; 178 179 mpz_init (want); 180 mpz_init (got); 181 182 mpz_mul_ui (want, x, (unsigned long) y); 183 mpz_add (want, w, want); 184 mpz_set (got, w); 185 mpz_addmul_ui (got, x, (unsigned long) y); 186 MPZ_CHECK_FORMAT (got); 187 if (mpz_cmp (want, got) != 0) 188 { 189 printf ("mpz_addmul_ui fail\n"); 190 fail: 191 mpz_trace ("w", w); 192 mpz_trace ("x", x); 193 printf ("y=0x%lX %lu\n", y, y); 194 mpz_trace ("want", want); 195 mpz_trace ("got ", got); 196 abort (); 197 } 198 199 mpz_mul_ui (want, x, y); 200 mpz_sub (want, w, want); 201 mpz_set (got, w); 202 mpz_submul_ui (got, x, y); 203 MPZ_CHECK_FORMAT (got); 204 if (mpz_cmp (want, got) != 0) 205 { 206 printf ("mpz_submul_ui fail\n"); 207 goto fail; 208 } 209 210 mpz_clear (want); 211 mpz_clear (got); 212 } 213 214 215 void 216 check_all (mpz_ptr w, mpz_ptr x, mpz_ptr y) 217 { 218 int swap, wneg, xneg, yneg; 219 220 MPZ_CHECK_FORMAT (w); 221 MPZ_CHECK_FORMAT (x); 222 MPZ_CHECK_FORMAT (y); 223 224 for (swap = 0; swap < 2; swap++) 225 { 226 for (wneg = 0; wneg < 2; wneg++) 227 { 228 for (xneg = 0; xneg < 2; xneg++) 229 { 230 for (yneg = 0; yneg < 2; yneg++) 231 { 232 check_one (w, x, y); 233 234 if (mpz_fits_ulong_p (y)) 235 check_one_ui (w, x, mpz_get_ui (y)); 236 237 mpz_neg (y, y); 238 } 239 mpz_neg (x, x); 240 } 241 mpz_neg (w, w); 242 } 243 mpz_swap (x, y); 244 } 245 } 246 247 void 248 check_data_inplace_ui (void) 249 { 250 static const struct { 251 mp_limb_t w[6]; 252 unsigned long y; 253 254 } data[] = { 255 256 { { 0 }, 0 }, 257 { { 0 }, 1 }, 258 { { 1 }, 1 }, 259 { { 2 }, 1 }, 260 261 { { 123 }, 1 }, 262 { { 123 }, ULONG_MAX }, 263 { { M }, 1 }, 264 { { M }, ULONG_MAX }, 265 266 { { 123, 456 }, 1 }, 267 { { M, M }, 1 }, 268 { { 123, 456 }, ULONG_MAX }, 269 { { M, M }, ULONG_MAX }, 270 271 { { 123, 456, 789 }, 1 }, 272 { { M, M, M }, 1 }, 273 { { 123, 456, 789 }, ULONG_MAX }, 274 { { M, M, M }, ULONG_MAX }, 275 }; 276 277 mpz_t w, y; 278 int i; 279 280 mpz_init (w); 281 mpz_init (y); 282 283 for (i = 0; i < numberof (data); i++) 284 { 285 mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w)); 286 mpz_set_ui (y, data[i].y); 287 check_all_inplace (w, y); 288 } 289 290 mpz_clear (w); 291 mpz_clear (y); 292 } 293 294 void 295 check_data (void) 296 { 297 static const struct { 298 mp_limb_t w[6]; 299 mp_limb_t x[6]; 300 mp_limb_t y[6]; 301 302 } data[] = { 303 304 /* reducing to zero */ 305 { { 1 }, { 1 }, { 1 } }, 306 { { 2 }, { 1 }, { 2 } }, 307 { { 0,1 }, { 0,1 }, { 1 } }, 308 309 /* reducing to 1 */ 310 { { 0,1 }, { M }, { 1 } }, 311 { { 0,0,1 }, { M,M }, { 1 } }, 312 { { 0,0,0,1 }, { M,M,M }, { 1 } }, 313 { { 0,0,0,0,1 }, { M,M,M,M }, { 1 } }, 314 315 /* reducing to -1 */ 316 { { M }, { 0,1 }, { 1 } }, 317 { { M,M }, { 0,0,1 }, { 1 } }, 318 { { M,M,M }, { 0,0,0,1 }, { 1 } }, 319 { { M,M,M,M }, { 0,0,0,0,1 }, { 1 } }, 320 321 /* carry out of addmul */ 322 { { M }, { 1 }, { 1 } }, 323 { { M,M }, { 1 }, { 1 } }, 324 { { M,M,M }, { 1 }, { 1 } }, 325 326 /* borrow from submul */ 327 { { 0,1 }, { 1 }, { 1 } }, 328 { { 0,0,1 }, { 1 }, { 1 } }, 329 { { 0,0,0,1 }, { 1 }, { 1 } }, 330 331 /* borrow from submul */ 332 { { 0,0,1 }, { 0,1 }, { 1 } }, 333 { { 0,0,0,1 }, { 0,1 }, { 1 } }, 334 { { 0,0,0,0,1 }, { 0,1 }, { 1 } }, 335 336 /* more borrow from submul */ 337 { { M }, { 0,1 }, { 1 } }, 338 { { M }, { 0,0,1 }, { 1 } }, 339 { { M }, { 0,0,0,1 }, { 1 } }, 340 { { M }, { 0,0,0,0,1 }, { 1 } }, 341 342 /* big borrow from submul */ 343 { { 0,0,1 }, { M,M }, { M } }, 344 { { 0,0,0,1 }, { M,M }, { M } }, 345 { { 0,0,0,0,1 }, { M,M }, { M } }, 346 347 /* small w */ 348 { { 0,1 }, { M,M }, { M } }, 349 { { 0,1 }, { M,M,M }, { M } }, 350 { { 0,1 }, { M,M,M,M }, { M } }, 351 { { 0,1 }, { M,M,M,M,M }, { M } }, 352 }; 353 354 mpz_t w, x, y; 355 int i; 356 357 mpz_init (w); 358 mpz_init (x); 359 mpz_init (y); 360 361 for (i = 0; i < numberof (data); i++) 362 { 363 mpz_set_n (w, data[i].w, (mp_size_t) numberof(data[i].w)); 364 mpz_set_n (x, data[i].x, (mp_size_t) numberof(data[i].x)); 365 mpz_set_n (y, data[i].y, (mp_size_t) numberof(data[i].y)); 366 check_all (w, x, y); 367 } 368 369 mpz_clear (w); 370 mpz_clear (x); 371 mpz_clear (y); 372 } 373 374 375 void 376 check_random (int argc, char *argv[]) 377 { 378 gmp_randstate_ptr rands = RANDS; 379 mpz_t w, x, y; 380 int i, reps = 2000; 381 382 mpz_init (w); 383 mpz_init (x); 384 mpz_init (y); 385 386 if (argc == 2) 387 reps = atoi (argv[1]); 388 389 for (i = 0; i < reps; i++) 390 { 391 mpz_errandomb (w, rands, 5*GMP_LIMB_BITS); 392 mpz_errandomb (x, rands, 5*GMP_LIMB_BITS); 393 mpz_errandomb (y, rands, 5*GMP_LIMB_BITS); 394 check_all (w, x, y); 395 check_all_inplace (w, y); 396 397 mpz_errandomb (w, rands, 5*GMP_LIMB_BITS); 398 mpz_errandomb (x, rands, 5*GMP_LIMB_BITS); 399 mpz_errandomb (y, rands, BITS_PER_ULONG); 400 check_all (w, x, y); 401 check_all_inplace (w, y); 402 } 403 404 mpz_clear (w); 405 mpz_clear (x); 406 mpz_clear (y); 407 } 408 409 410 int 411 main (int argc, char *argv[]) 412 { 413 tests_start (); 414 mp_trace_base = -16; 415 416 check_data (); 417 check_data_inplace_ui (); 418 check_random (argc, argv); 419 420 tests_end (); 421 exit (0); 422 }