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