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
testmain(int argc,char ** argv)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