github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-fdiv.c (about) 1 /* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr, mpz_fdiv_q, 2 mpz_fdiv_r, mpz_mul. 3 4 Copyright 1993, 1994, 1996, 2000, 2001 Free Software 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 dump_abort (mpz_t, mpz_t); 29 void debug_mp (mpz_t, int); 30 31 int 32 main (int argc, char **argv) 33 { 34 mpz_t dividend, divisor; 35 mpz_t quotient, remainder; 36 mpz_t quotient2, remainder2; 37 mpz_t temp; 38 mp_size_t dividend_size, divisor_size; 39 int i; 40 int reps = 1000; 41 gmp_randstate_ptr rands; 42 mpz_t bs; 43 unsigned long bsi, size_range; 44 45 tests_start (); 46 rands = RANDS; 47 48 mpz_init (bs); 49 50 if (argc == 2) 51 reps = atoi (argv[1]); 52 53 mpz_init (dividend); 54 mpz_init (divisor); 55 mpz_init (quotient); 56 mpz_init (remainder); 57 mpz_init (quotient2); 58 mpz_init (remainder2); 59 mpz_init (temp); 60 61 for (i = 0; i < reps; i++) 62 { 63 mpz_urandomb (bs, rands, 32); 64 size_range = mpz_get_ui (bs) % 16 + 2; /* 0..131071 bit operands */ 65 66 do 67 { 68 mpz_urandomb (bs, rands, size_range); 69 divisor_size = mpz_get_ui (bs); 70 mpz_rrandomb (divisor, rands, divisor_size); 71 } 72 while (mpz_sgn (divisor) == 0); 73 74 mpz_urandomb (bs, rands, size_range); 75 dividend_size = mpz_get_ui (bs) + divisor_size; 76 mpz_rrandomb (dividend, rands, dividend_size); 77 78 mpz_urandomb (bs, rands, 2); 79 bsi = mpz_get_ui (bs); 80 if ((bsi & 1) != 0) 81 mpz_neg (dividend, dividend); 82 if ((bsi & 2) != 0) 83 mpz_neg (divisor, divisor); 84 85 /* printf ("%ld %ld\n", SIZ (dividend), SIZ (divisor)); */ 86 87 mpz_fdiv_qr (quotient, remainder, dividend, divisor); 88 mpz_fdiv_q (quotient2, dividend, divisor); 89 mpz_fdiv_r (remainder2, dividend, divisor); 90 91 /* First determine that the quotients and remainders computed 92 with different functions are equal. */ 93 if (mpz_cmp (quotient, quotient2) != 0) 94 dump_abort (dividend, divisor); 95 if (mpz_cmp (remainder, remainder2) != 0) 96 dump_abort (dividend, divisor); 97 98 /* Check if the sign of the quotient is correct. */ 99 if (mpz_cmp_ui (quotient, 0) != 0) 100 if ((mpz_cmp_ui (quotient, 0) < 0) 101 != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0)) 102 dump_abort (dividend, divisor); 103 104 /* Check if the remainder has the same sign as the divisor 105 (quotient rounded towards minus infinity). */ 106 if (mpz_cmp_ui (remainder, 0) != 0) 107 if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (divisor, 0) < 0)) 108 dump_abort (dividend, divisor); 109 110 mpz_mul (temp, quotient, divisor); 111 mpz_add (temp, temp, remainder); 112 if (mpz_cmp (temp, dividend) != 0) 113 dump_abort (dividend, divisor); 114 115 mpz_abs (temp, divisor); 116 mpz_abs (remainder, remainder); 117 if (mpz_cmp (remainder, temp) >= 0) 118 dump_abort (dividend, divisor); 119 } 120 121 mpz_clear (bs); 122 mpz_clear (dividend); 123 mpz_clear (divisor); 124 mpz_clear (quotient); 125 mpz_clear (remainder); 126 mpz_clear (quotient2); 127 mpz_clear (remainder2); 128 mpz_clear (temp); 129 130 tests_end (); 131 exit (0); 132 } 133 134 void 135 dump_abort (mpz_t dividend, mpz_t divisor) 136 { 137 fprintf (stderr, "ERROR\n"); 138 fprintf (stderr, "dividend = "); debug_mp (dividend, -16); 139 fprintf (stderr, "divisor = "); debug_mp (divisor, -16); 140 abort(); 141 } 142 143 void 144 debug_mp (mpz_t x, int base) 145 { 146 mpz_out_str (stderr, base, x); fputc ('\n', stderr); 147 }