blob: be2f6b1b4950cf067d7e338fa3988bac471b0baf [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/*
2
3Copyright 2012, 2013, 2018 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the 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
29typedef void div_qr_func (mpz_t, mpz_t, const mpz_t, const mpz_t);
30typedef unsigned long div_qr_ui_func (mpz_t, mpz_t, const mpz_t, unsigned long);
31typedef void div_func (mpz_t, const mpz_t, const mpz_t);
32typedef unsigned long div_x_ui_func (mpz_t, const mpz_t, unsigned long);
33typedef unsigned long div_ui_func (const mpz_t, unsigned long);
34
35void
36testmain (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}