1 /* 2 3 Copyright 2012, 2013, 2018 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 * const 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 * const 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 * const div_r_ui[3] = 77 { 78 mpz_cdiv_r_ui, mpz_fdiv_r_ui, mpz_tdiv_r_ui 79 }; 80 static div_ui_func * const 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 mpz_set_si (r, -6); 135 if (j == 0 && mpz_sgn (b) < 0) /* ceil, negative divisor */ 136 { 137 mpz_mod (r, a, b); 138 if (mpz_cmp (r, rr)) 139 { 140 fprintf (stderr, "mpz_mod failed:\n"); 141 dump ("a", a); 142 dump ("b", b); 143 dump ("r ", r); 144 dump ("rref", rr); 145 abort (); 146 } 147 } 148 149 if (j == 1 && mpz_sgn (b) > 0) /* floor, positive divisor */ 150 { 151 mpz_mod (r, a, b); 152 if (mpz_cmp (r, rr)) 153 { 154 fprintf (stderr, "mpz_mod failed:\n"); 155 dump ("a", a); 156 dump ("b", b); 157 dump ("r ", r); 158 dump ("rref", rr); 159 abort (); 160 } 161 } 162 163 if (mpz_fits_ulong_p (b)) 164 { 165 unsigned long rl; 166 167 mpz_set_si (r, -7); 168 mpz_set_ui (q, ~7); 169 rl = div_qr_ui[j] (q, r, a, mpz_get_ui (b)); 170 if (rl != mpz_get_ui (rr) 171 || mpz_cmp (r, rr) || mpz_cmp (q, rq)) 172 { 173 fprintf (stderr, "mpz_%cdiv_qr_ui failed:\n", name[j]); 174 dump ("a", a); 175 dump ("b", b); 176 fprintf(stderr, "rl = %lx\n", rl); 177 dump ("r ", r); 178 dump ("rref", rr); 179 dump ("q ", q); 180 dump ("qref", rq); 181 abort (); 182 } 183 184 mpz_set_si (q, 3); 185 rl = div_q_ui[j] (q, a, mpz_get_ui (b)); 186 if (rl != mpz_get_ui (rr) || mpz_cmp (q, rq)) 187 { 188 fprintf (stderr, "mpz_%cdiv_q_ui failed:\n", name[j]); 189 dump ("a", a); 190 dump ("b", b); 191 fprintf(stderr, "rl = %lx\n", rl); 192 dump ("rref", rr); 193 dump ("q ", q); 194 dump ("qref", rq); 195 abort (); 196 } 197 198 mpz_set_ui (r, 7); 199 rl = div_r_ui[j] (r, a, mpz_get_ui (b)); 200 if (rl != mpz_get_ui (rr) || mpz_cmp (r, rr)) 201 { 202 fprintf (stderr, "mpz_%cdiv_r_ui failed:\n", name[j]); 203 dump ("a", a); 204 dump ("b", b); 205 fprintf(stderr, "rl = %lx\n", rl); 206 dump ("r ", r); 207 dump ("rref", rr); 208 abort (); 209 } 210 211 rl = div_ui[j] (a, mpz_get_ui (b)); 212 if (rl != mpz_get_ui (rr)) 213 { 214 fprintf (stderr, "mpz_%cdiv_ui failed:\n", name[j]); 215 dump ("a", a); 216 dump ("b", b); 217 fprintf(stderr, "rl = %lx\n", rl); 218 dump ("rref", rr); 219 abort (); 220 } 221 222 if (j == 0) /* do this once, not for all roundings */ 223 { 224 div_p = mpz_divisible_ui_p (a, mpz_get_ui (b)); 225 if ((mpz_sgn (r) == 0) ^ (div_p != 0)) 226 { 227 fprintf (stderr, "mpz_divisible_ui_p failed:\n"); 228 dump ("a", a); 229 dump ("b", b); 230 dump ("r ", r); 231 abort (); 232 } 233 } 234 235 if (j == 1) /* floor */ 236 { 237 mpz_set_si (r, -2); 238 mpz_mod_ui (r, a, mpz_get_ui (b)); 239 if (mpz_cmp (r, rr)) 240 { 241 fprintf (stderr, "mpz_mod failed:\n"); 242 dump ("a", a); 243 dump ("b", b); 244 dump ("r ", r); 245 dump ("rref", rr); 246 abort (); 247 } 248 } 249 } 250 } 251 } 252 mpz_clear (a); 253 mpz_clear (b); 254 mpz_clear (r); 255 mpz_clear (q); 256 mpz_clear (rr); 257 mpz_clear (rq); 258 } 259