github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/t-div.c (about) 1 /* 2 3 Copyright 2012, 2013 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 <assert.h> 21 #include <stdlib.h> 22 #include <stdio.h> 23 24 #include "testutils.h" 25 26 #define MAXBITS 400 27 #define COUNT 10000 28 29 typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t); 30 typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long); 31 typedef void div_func (mpz_t, const mpz_t, const mpz_t); 32 typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long); 33 typedef unsigned long div_ui_func (const mpz_t, unsigned long); 34 35 void 36 testmain (int argc, char **argv) 37 { 38 unsigned i; 39 mpz_t a, b, q, r, rq, rr; 40 int div_p; 41 42 mpz_init (a); 43 mpz_init (b); 44 mpz_init (r); 45 mpz_init (q); 46 mpz_init (rr); 47 mpz_init (rq); 48 49 for (i = 0; i < COUNT; i++) 50 { 51 unsigned j; 52 for (j = 0; j < 3; j++) 53 { 54 static const enum hex_random_op ops[3] = { OP_CDIV, OP_FDIV, OP_TDIV }; 55 static const char name[3] = { 'c', 'f', 't'}; 56 static div_qr_func * const div_qr [3] = 57 { 58 mpz_cdiv_qr, mpz_fdiv_qr, mpz_tdiv_qr 59 }; 60 static div_qr_ui_func *div_qr_ui[3] = 61 { 62 mpz_cdiv_qr_ui, mpz_fdiv_qr_ui, mpz_tdiv_qr_ui 63 }; 64 static div_func * const div_q [3] = 65 { 66 mpz_cdiv_q, mpz_fdiv_q, mpz_tdiv_q 67 }; 68 static div_x_ui_func *div_q_ui[3] = 69 { 70 mpz_cdiv_q_ui, mpz_fdiv_q_ui, mpz_tdiv_q_ui 71 }; 72 static div_func * const div_r [3] = 73 { 74 mpz_cdiv_r, mpz_fdiv_r, mpz_tdiv_r 75 }; 76 static div_x_ui_func *div_r_ui[3] = 77 { 78 mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui 79 }; 80 static div_ui_func *div_ui[3] = 81 { 82 mpz_cdiv_ui, mpz_fdiv_ui, mpz_tdiv_ui 83 }; 84 85 mini_random_op4 (ops[j], MAXBITS, a, b, rq, rr); 86 div_qr[j] (q, r, a, b); 87 if (mpz_cmp (r, rr) || mpz_cmp (q, rq)) 88 { 89 fprintf (stderr, "mpz_%cdiv_qr failed:\n", name[j]); 90 dump ("a", a); 91 dump ("b", b); 92 dump ("r ", r); 93 dump ("rref", rr); 94 dump ("q ", q); 95 dump ("qref", rq); 96 abort (); 97 } 98 mpz_set_si (q, -5); 99 div_q[j] (q, a, b); 100 if (mpz_cmp (q, rq)) 101 { 102 fprintf (stderr, "mpz_%cdiv_q failed:\n", name[j]); 103 dump ("a", a); 104 dump ("b", b); 105 dump ("q ", q); 106 dump ("qref", rq); 107 abort (); 108 } 109 mpz_set_ui (r, ~5); 110 div_r[j] (r, a, b); 111 if (mpz_cmp (r, rr)) 112 { 113 fprintf (stderr, "mpz_%cdiv_r failed:\n", name[j]); 114 dump ("a", a); 115 dump ("b", b); 116 dump ("r ", r); 117 dump ("rref", rr); 118 abort (); 119 } 120 121 if (j == 0) /* do this once, not for all roundings */ 122 { 123 div_p = mpz_divisible_p (a, b); 124 if ((mpz_sgn (r) == 0) ^ (div_p != 0)) 125 { 126 fprintf (stderr, "mpz_divisible_p failed:\n"); 127 dump ("a", a); 128 dump ("b", b); 129 dump ("r ", r); 130 abort (); 131 } 132 } 133 134 if (j == 0 && mpz_sgn (b) < 0) /* ceil, negative divisor */ 135 { 136 mpz_mod (r, a, b); 137 if (mpz_cmp (r, rr)) 138 { 139 fprintf (stderr, "mpz_mod failed:\n"); 140 dump ("a", a); 141 dump ("b", b); 142 dump ("r ", r); 143 dump ("rref", rr); 144 abort (); 145 } 146 } 147 148 if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */ 149 { 150 mpz_mod (r, a, b); 151 if (mpz_cmp (r, rr)) 152 { 153 fprintf (stderr, "mpz_mod failed:\n"); 154 dump ("a", a); 155 dump ("b", b); 156 dump ("r ", r); 157 dump ("rref", rr); 158 abort (); 159 } 160 } 161 162 if (mpz_fits_ulong_p (b)) 163 { 164 mp_limb_t rl; 165 166 rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b)); 167 if (rl != mpz_get_ui (rr) 168 || mpz_cmp (r, rr) || mpz_cmp (q, rq)) 169 { 170 fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]); 171 dump ("a", a); 172 dump ("b", b); 173 fprintf(stderr, "rl = %lx\n", rl); 174 dump ("r ", r); 175 dump ("rref", rr); 176 dump ("q ", q); 177 dump ("qref", rq); 178 abort (); 179 } 180 181 mpz_set_si (q, 3); 182 rl = div_q_ui[j] (q, a, mpz_get_ui (b)); 183 if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq)) 184 { 185 fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]); 186 dump ("a", a); 187 dump ("b", b); 188 fprintf(stderr, "rl = %lx\n", rl); 189 dump ("rref", rr); 190 dump ("q ", q); 191 dump ("qref", rq); 192 abort (); 193 } 194 195 mpz_set_ui (r, 7); 196 rl = div_r_ui[j] (r, a, mpz_get_ui (b)); 197 if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr)) 198 { 199 fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]); 200 dump ("a", a); 201 dump ("b", b); 202 fprintf(stderr, "rl = %lx\n", rl); 203 dump ("r ", r); 204 dump ("rref", rr); 205 abort (); 206 } 207 208 rl = div_ui[j] (a, mpz_get_ui (b)); 209 if (rl != mpz_get_ui (rr)) 210 { 211 fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]); 212 dump ("a", a); 213 dump ("b", b); 214 fprintf(stderr, "rl = %lx\n", rl); 215 dump ("rref", rr); 216 abort (); 217 } 218 219 if (j == 0) /* do this once, not for all roundings */ 220 { 221 div_p = mpz_divisible_ui_p (a, mpz_get_ui (b)); 222 if ((mpz_sgn (r) == 0) ^ (div_p != 0)) 223 { 224 fprintf (stderr, "mpz_divisible_ui_p failed:\n"); 225 dump ("a", a); 226 dump ("b", b); 227 dump ("r ", r); 228 abort (); 229 } 230 } 231 232 if (j == 1) /* floor */ 233 { 234 mpz_mod_ui (r, a, mpz_get_ui (b)); 235 if (mpz_cmp (r, rr)) 236 { 237 fprintf (stderr, "mpz_mod failed:\n"); 238 dump ("a", a); 239 dump ("b", b); 240 dump ("r ", r); 241 dump ("rref", rr); 242 abort (); 243 } 244 } 245 } 246 } 247 } 248 mpz_clear (a); 249 mpz_clear (b); 250 mpz_clear (r); 251 mpz_clear (q); 252 mpz_clear (rr); 253 mpz_clear (rq); 254 }