tdiv_qr.c revision 1.1.1.2 1 1.1 mrg /* mpn_tdiv_qr -- Divide the numerator (np,nn) by the denominator (dp,dn) and
2 1.1 mrg write the nn-dn+1 quotient limbs at qp and the dn remainder limbs at rp. If
3 1.1 mrg qxn is non-zero, generate that many fraction limbs and append them after the
4 1.1 mrg other quotient limbs, and update the remainder accordingly. The input
5 1.1 mrg operands are unaffected.
6 1.1 mrg
7 1.1 mrg Preconditions:
8 1.1 mrg 1. The most significant limb of of the divisor must be non-zero.
9 1.1 mrg 2. nn >= dn, even if qxn is non-zero. (??? relax this ???)
10 1.1 mrg
11 1.1 mrg The time complexity of this is O(qn*qn+M(dn,qn)), where M(m,n) is the time
12 1.1 mrg complexity of multiplication.
13 1.1 mrg
14 1.1.1.2 mrg Copyright 1997, 2000-2002, 2005, 2009 Free Software Foundation, Inc.
15 1.1 mrg
16 1.1 mrg This file is part of the GNU MP Library.
17 1.1 mrg
18 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify
19 1.1.1.2 mrg it under the terms of either:
20 1.1.1.2 mrg
21 1.1.1.2 mrg * the GNU Lesser General Public License as published by the Free
22 1.1.1.2 mrg Software Foundation; either version 3 of the License, or (at your
23 1.1.1.2 mrg option) any later version.
24 1.1.1.2 mrg
25 1.1.1.2 mrg or
26 1.1.1.2 mrg
27 1.1.1.2 mrg * the GNU General Public License as published by the Free Software
28 1.1.1.2 mrg Foundation; either version 2 of the License, or (at your option) any
29 1.1.1.2 mrg later version.
30 1.1.1.2 mrg
31 1.1.1.2 mrg or both in parallel, as here.
32 1.1 mrg
33 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
34 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
35 1.1.1.2 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
36 1.1.1.2 mrg for more details.
37 1.1 mrg
38 1.1.1.2 mrg You should have received copies of the GNU General Public License and the
39 1.1.1.2 mrg GNU Lesser General Public License along with the GNU MP Library. If not,
40 1.1.1.2 mrg see https://www.gnu.org/licenses/. */
41 1.1 mrg
42 1.1 mrg #include "gmp.h"
43 1.1 mrg #include "gmp-impl.h"
44 1.1 mrg #include "longlong.h"
45 1.1 mrg
46 1.1 mrg
47 1.1 mrg void
48 1.1 mrg mpn_tdiv_qr (mp_ptr qp, mp_ptr rp, mp_size_t qxn,
49 1.1 mrg mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn)
50 1.1 mrg {
51 1.1 mrg ASSERT_ALWAYS (qxn == 0);
52 1.1 mrg
53 1.1 mrg ASSERT (nn >= 0);
54 1.1 mrg ASSERT (dn >= 0);
55 1.1 mrg ASSERT (dn == 0 || dp[dn - 1] != 0);
56 1.1 mrg ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, np, nn));
57 1.1 mrg ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, dp, dn));
58 1.1 mrg
59 1.1 mrg switch (dn)
60 1.1 mrg {
61 1.1 mrg case 0:
62 1.1 mrg DIVIDE_BY_ZERO;
63 1.1 mrg
64 1.1 mrg case 1:
65 1.1 mrg {
66 1.1 mrg rp[0] = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, dp[0]);
67 1.1 mrg return;
68 1.1 mrg }
69 1.1 mrg
70 1.1 mrg case 2:
71 1.1 mrg {
72 1.1 mrg mp_ptr n2p, d2p;
73 1.1 mrg mp_limb_t qhl, cy;
74 1.1 mrg TMP_DECL;
75 1.1 mrg TMP_MARK;
76 1.1 mrg if ((dp[1] & GMP_NUMB_HIGHBIT) == 0)
77 1.1 mrg {
78 1.1 mrg int cnt;
79 1.1 mrg mp_limb_t dtmp[2];
80 1.1 mrg count_leading_zeros (cnt, dp[1]);
81 1.1 mrg cnt -= GMP_NAIL_BITS;
82 1.1 mrg d2p = dtmp;
83 1.1 mrg d2p[1] = (dp[1] << cnt) | (dp[0] >> (GMP_NUMB_BITS - cnt));
84 1.1 mrg d2p[0] = (dp[0] << cnt) & GMP_NUMB_MASK;
85 1.1 mrg n2p = TMP_ALLOC_LIMBS (nn + 1);
86 1.1 mrg cy = mpn_lshift (n2p, np, nn, cnt);
87 1.1 mrg n2p[nn] = cy;
88 1.1 mrg qhl = mpn_divrem_2 (qp, 0L, n2p, nn + (cy != 0), d2p);
89 1.1 mrg if (cy == 0)
90 1.1 mrg qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */
91 1.1 mrg rp[0] = (n2p[0] >> cnt)
92 1.1 mrg | ((n2p[1] << (GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK);
93 1.1 mrg rp[1] = (n2p[1] >> cnt);
94 1.1 mrg }
95 1.1 mrg else
96 1.1 mrg {
97 1.1 mrg d2p = (mp_ptr) dp;
98 1.1 mrg n2p = TMP_ALLOC_LIMBS (nn);
99 1.1 mrg MPN_COPY (n2p, np, nn);
100 1.1 mrg qhl = mpn_divrem_2 (qp, 0L, n2p, nn, d2p);
101 1.1 mrg qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */
102 1.1 mrg rp[0] = n2p[0];
103 1.1 mrg rp[1] = n2p[1];
104 1.1 mrg }
105 1.1 mrg TMP_FREE;
106 1.1 mrg return;
107 1.1 mrg }
108 1.1 mrg
109 1.1 mrg default:
110 1.1 mrg {
111 1.1 mrg int adjust;
112 1.1 mrg gmp_pi1_t dinv;
113 1.1 mrg TMP_DECL;
114 1.1 mrg TMP_MARK;
115 1.1 mrg adjust = np[nn - 1] >= dp[dn - 1]; /* conservative tests for quotient size */
116 1.1 mrg if (nn + adjust >= 2 * dn)
117 1.1 mrg {
118 1.1 mrg mp_ptr n2p, d2p;
119 1.1 mrg mp_limb_t cy;
120 1.1 mrg int cnt;
121 1.1 mrg
122 1.1 mrg qp[nn - dn] = 0; /* zero high quotient limb */
123 1.1 mrg if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0) /* normalize divisor */
124 1.1 mrg {
125 1.1 mrg count_leading_zeros (cnt, dp[dn - 1]);
126 1.1 mrg cnt -= GMP_NAIL_BITS;
127 1.1 mrg d2p = TMP_ALLOC_LIMBS (dn);
128 1.1 mrg mpn_lshift (d2p, dp, dn, cnt);
129 1.1 mrg n2p = TMP_ALLOC_LIMBS (nn + 1);
130 1.1 mrg cy = mpn_lshift (n2p, np, nn, cnt);
131 1.1 mrg n2p[nn] = cy;
132 1.1 mrg nn += adjust;
133 1.1 mrg }
134 1.1 mrg else
135 1.1 mrg {
136 1.1 mrg cnt = 0;
137 1.1 mrg d2p = (mp_ptr) dp;
138 1.1 mrg n2p = TMP_ALLOC_LIMBS (nn + 1);
139 1.1 mrg MPN_COPY (n2p, np, nn);
140 1.1 mrg n2p[nn] = 0;
141 1.1 mrg nn += adjust;
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg invert_pi1 (dinv, d2p[dn - 1], d2p[dn - 2]);
145 1.1 mrg if (BELOW_THRESHOLD (dn, DC_DIV_QR_THRESHOLD))
146 1.1 mrg mpn_sbpi1_div_qr (qp, n2p, nn, d2p, dn, dinv.inv32);
147 1.1 mrg else if (BELOW_THRESHOLD (dn, MUPI_DIV_QR_THRESHOLD) || /* fast condition */
148 1.1 mrg BELOW_THRESHOLD (nn, 2 * MU_DIV_QR_THRESHOLD) || /* fast condition */
149 1.1 mrg (double) (2 * (MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD)) * dn /* slow... */
150 1.1 mrg + (double) MUPI_DIV_QR_THRESHOLD * nn > (double) dn * nn) /* ...condition */
151 1.1 mrg mpn_dcpi1_div_qr (qp, n2p, nn, d2p, dn, &dinv);
152 1.1 mrg else
153 1.1 mrg {
154 1.1 mrg mp_size_t itch = mpn_mu_div_qr_itch (nn, dn, 0);
155 1.1 mrg mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
156 1.1 mrg mpn_mu_div_qr (qp, rp, n2p, nn, d2p, dn, scratch);
157 1.1 mrg n2p = rp;
158 1.1 mrg }
159 1.1 mrg
160 1.1 mrg if (cnt != 0)
161 1.1 mrg mpn_rshift (rp, n2p, dn, cnt);
162 1.1 mrg else
163 1.1 mrg MPN_COPY (rp, n2p, dn);
164 1.1 mrg TMP_FREE;
165 1.1 mrg return;
166 1.1 mrg }
167 1.1 mrg
168 1.1 mrg /* When we come here, the numerator/partial remainder is less
169 1.1 mrg than twice the size of the denominator. */
170 1.1 mrg
171 1.1 mrg {
172 1.1 mrg /* Problem:
173 1.1 mrg
174 1.1 mrg Divide a numerator N with nn limbs by a denominator D with dn
175 1.1 mrg limbs forming a quotient of qn=nn-dn+1 limbs. When qn is small
176 1.1 mrg compared to dn, conventional division algorithms perform poorly.
177 1.1 mrg We want an algorithm that has an expected running time that is
178 1.1 mrg dependent only on qn.
179 1.1 mrg
180 1.1 mrg Algorithm (very informally stated):
181 1.1 mrg
182 1.1 mrg 1) Divide the 2 x qn most significant limbs from the numerator
183 1.1 mrg by the qn most significant limbs from the denominator. Call
184 1.1 mrg the result qest. This is either the correct quotient, but
185 1.1 mrg might be 1 or 2 too large. Compute the remainder from the
186 1.1.1.2 mrg division. (This step is implemented by an mpn_divrem call.)
187 1.1 mrg
188 1.1 mrg 2) Is the most significant limb from the remainder < p, where p
189 1.1 mrg is the product of the most significant limb from the quotient
190 1.1 mrg and the next(d)? (Next(d) denotes the next ignored limb from
191 1.1 mrg the denominator.) If it is, decrement qest, and adjust the
192 1.1 mrg remainder accordingly.
193 1.1 mrg
194 1.1 mrg 3) Is the remainder >= qest? If it is, qest is the desired
195 1.1 mrg quotient. The algorithm terminates.
196 1.1 mrg
197 1.1 mrg 4) Subtract qest x next(d) from the remainder. If there is
198 1.1 mrg borrow out, decrement qest, and adjust the remainder
199 1.1 mrg accordingly.
200 1.1 mrg
201 1.1 mrg 5) Skip one word from the denominator (i.e., let next(d) denote
202 1.1 mrg the next less significant limb. */
203 1.1 mrg
204 1.1 mrg mp_size_t qn;
205 1.1 mrg mp_ptr n2p, d2p;
206 1.1 mrg mp_ptr tp;
207 1.1 mrg mp_limb_t cy;
208 1.1 mrg mp_size_t in, rn;
209 1.1 mrg mp_limb_t quotient_too_large;
210 1.1 mrg unsigned int cnt;
211 1.1 mrg
212 1.1 mrg qn = nn - dn;
213 1.1 mrg qp[qn] = 0; /* zero high quotient limb */
214 1.1 mrg qn += adjust; /* qn cannot become bigger */
215 1.1 mrg
216 1.1 mrg if (qn == 0)
217 1.1 mrg {
218 1.1 mrg MPN_COPY (rp, np, dn);
219 1.1 mrg TMP_FREE;
220 1.1 mrg return;
221 1.1 mrg }
222 1.1 mrg
223 1.1 mrg in = dn - qn; /* (at least partially) ignored # of limbs in ops */
224 1.1 mrg /* Normalize denominator by shifting it to the left such that its
225 1.1 mrg most significant bit is set. Then shift the numerator the same
226 1.1 mrg amount, to mathematically preserve quotient. */
227 1.1 mrg if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0)
228 1.1 mrg {
229 1.1 mrg count_leading_zeros (cnt, dp[dn - 1]);
230 1.1 mrg cnt -= GMP_NAIL_BITS;
231 1.1 mrg
232 1.1 mrg d2p = TMP_ALLOC_LIMBS (qn);
233 1.1 mrg mpn_lshift (d2p, dp + in, qn, cnt);
234 1.1 mrg d2p[0] |= dp[in - 1] >> (GMP_NUMB_BITS - cnt);
235 1.1 mrg
236 1.1 mrg n2p = TMP_ALLOC_LIMBS (2 * qn + 1);
237 1.1 mrg cy = mpn_lshift (n2p, np + nn - 2 * qn, 2 * qn, cnt);
238 1.1 mrg if (adjust)
239 1.1 mrg {
240 1.1 mrg n2p[2 * qn] = cy;
241 1.1 mrg n2p++;
242 1.1 mrg }
243 1.1 mrg else
244 1.1 mrg {
245 1.1 mrg n2p[0] |= np[nn - 2 * qn - 1] >> (GMP_NUMB_BITS - cnt);
246 1.1 mrg }
247 1.1 mrg }
248 1.1 mrg else
249 1.1 mrg {
250 1.1 mrg cnt = 0;
251 1.1 mrg d2p = (mp_ptr) dp + in;
252 1.1 mrg
253 1.1 mrg n2p = TMP_ALLOC_LIMBS (2 * qn + 1);
254 1.1 mrg MPN_COPY (n2p, np + nn - 2 * qn, 2 * qn);
255 1.1 mrg if (adjust)
256 1.1 mrg {
257 1.1 mrg n2p[2 * qn] = 0;
258 1.1 mrg n2p++;
259 1.1 mrg }
260 1.1 mrg }
261 1.1 mrg
262 1.1 mrg /* Get an approximate quotient using the extracted operands. */
263 1.1 mrg if (qn == 1)
264 1.1 mrg {
265 1.1 mrg mp_limb_t q0, r0;
266 1.1 mrg udiv_qrnnd (q0, r0, n2p[1], n2p[0] << GMP_NAIL_BITS, d2p[0] << GMP_NAIL_BITS);
267 1.1 mrg n2p[0] = r0 >> GMP_NAIL_BITS;
268 1.1 mrg qp[0] = q0;
269 1.1 mrg }
270 1.1 mrg else if (qn == 2)
271 1.1 mrg mpn_divrem_2 (qp, 0L, n2p, 4L, d2p); /* FIXME: obsolete function */
272 1.1 mrg else
273 1.1 mrg {
274 1.1 mrg invert_pi1 (dinv, d2p[qn - 1], d2p[qn - 2]);
275 1.1 mrg if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD))
276 1.1 mrg mpn_sbpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, dinv.inv32);
277 1.1 mrg else if (BELOW_THRESHOLD (qn, MU_DIV_QR_THRESHOLD))
278 1.1 mrg mpn_dcpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, &dinv);
279 1.1 mrg else
280 1.1 mrg {
281 1.1 mrg mp_size_t itch = mpn_mu_div_qr_itch (2 * qn, qn, 0);
282 1.1 mrg mp_ptr scratch = TMP_ALLOC_LIMBS (itch);
283 1.1 mrg mp_ptr r2p = rp;
284 1.1 mrg if (np == r2p) /* If N and R share space, put ... */
285 1.1 mrg r2p += nn - qn; /* intermediate remainder at N's upper end. */
286 1.1 mrg mpn_mu_div_qr (qp, r2p, n2p, 2 * qn, d2p, qn, scratch);
287 1.1 mrg MPN_COPY (n2p, r2p, qn);
288 1.1 mrg }
289 1.1 mrg }
290 1.1 mrg
291 1.1 mrg rn = qn;
292 1.1 mrg /* Multiply the first ignored divisor limb by the most significant
293 1.1 mrg quotient limb. If that product is > the partial remainder's
294 1.1 mrg most significant limb, we know the quotient is too large. This
295 1.1 mrg test quickly catches most cases where the quotient is too large;
296 1.1 mrg it catches all cases where the quotient is 2 too large. */
297 1.1 mrg {
298 1.1 mrg mp_limb_t dl, x;
299 1.1 mrg mp_limb_t h, dummy;
300 1.1 mrg
301 1.1 mrg if (in - 2 < 0)
302 1.1 mrg dl = 0;
303 1.1 mrg else
304 1.1 mrg dl = dp[in - 2];
305 1.1 mrg
306 1.1 mrg #if GMP_NAIL_BITS == 0
307 1.1 mrg x = (dp[in - 1] << cnt) | ((dl >> 1) >> ((~cnt) % GMP_LIMB_BITS));
308 1.1 mrg #else
309 1.1 mrg x = (dp[in - 1] << cnt) & GMP_NUMB_MASK;
310 1.1 mrg if (cnt != 0)
311 1.1 mrg x |= dl >> (GMP_NUMB_BITS - cnt);
312 1.1 mrg #endif
313 1.1 mrg umul_ppmm (h, dummy, x, qp[qn - 1] << GMP_NAIL_BITS);
314 1.1 mrg
315 1.1 mrg if (n2p[qn - 1] < h)
316 1.1 mrg {
317 1.1 mrg mp_limb_t cy;
318 1.1 mrg
319 1.1 mrg mpn_decr_u (qp, (mp_limb_t) 1);
320 1.1 mrg cy = mpn_add_n (n2p, n2p, d2p, qn);
321 1.1 mrg if (cy)
322 1.1 mrg {
323 1.1 mrg /* The partial remainder is safely large. */
324 1.1 mrg n2p[qn] = cy;
325 1.1 mrg ++rn;
326 1.1 mrg }
327 1.1 mrg }
328 1.1 mrg }
329 1.1 mrg
330 1.1 mrg quotient_too_large = 0;
331 1.1 mrg if (cnt != 0)
332 1.1 mrg {
333 1.1 mrg mp_limb_t cy1, cy2;
334 1.1 mrg
335 1.1 mrg /* Append partially used numerator limb to partial remainder. */
336 1.1 mrg cy1 = mpn_lshift (n2p, n2p, rn, GMP_NUMB_BITS - cnt);
337 1.1 mrg n2p[0] |= np[in - 1] & (GMP_NUMB_MASK >> cnt);
338 1.1 mrg
339 1.1 mrg /* Update partial remainder with partially used divisor limb. */
340 1.1 mrg cy2 = mpn_submul_1 (n2p, qp, qn, dp[in - 1] & (GMP_NUMB_MASK >> cnt));
341 1.1 mrg if (qn != rn)
342 1.1 mrg {
343 1.1 mrg ASSERT_ALWAYS (n2p[qn] >= cy2);
344 1.1 mrg n2p[qn] -= cy2;
345 1.1 mrg }
346 1.1 mrg else
347 1.1 mrg {
348 1.1 mrg n2p[qn] = cy1 - cy2; /* & GMP_NUMB_MASK; */
349 1.1 mrg
350 1.1 mrg quotient_too_large = (cy1 < cy2);
351 1.1 mrg ++rn;
352 1.1 mrg }
353 1.1 mrg --in;
354 1.1 mrg }
355 1.1 mrg /* True: partial remainder now is neutral, i.e., it is not shifted up. */
356 1.1 mrg
357 1.1 mrg tp = TMP_ALLOC_LIMBS (dn);
358 1.1 mrg
359 1.1 mrg if (in < qn)
360 1.1 mrg {
361 1.1 mrg if (in == 0)
362 1.1 mrg {
363 1.1 mrg MPN_COPY (rp, n2p, rn);
364 1.1 mrg ASSERT_ALWAYS (rn == dn);
365 1.1 mrg goto foo;
366 1.1 mrg }
367 1.1 mrg mpn_mul (tp, qp, qn, dp, in);
368 1.1 mrg }
369 1.1 mrg else
370 1.1 mrg mpn_mul (tp, dp, in, qp, qn);
371 1.1 mrg
372 1.1 mrg cy = mpn_sub (n2p, n2p, rn, tp + in, qn);
373 1.1 mrg MPN_COPY (rp + in, n2p, dn - in);
374 1.1 mrg quotient_too_large |= cy;
375 1.1 mrg cy = mpn_sub_n (rp, np, tp, in);
376 1.1 mrg cy = mpn_sub_1 (rp + in, rp + in, rn, cy);
377 1.1 mrg quotient_too_large |= cy;
378 1.1 mrg foo:
379 1.1 mrg if (quotient_too_large)
380 1.1 mrg {
381 1.1 mrg mpn_decr_u (qp, (mp_limb_t) 1);
382 1.1 mrg mpn_add_n (rp, rp, dp, dn);
383 1.1 mrg }
384 1.1 mrg }
385 1.1 mrg TMP_FREE;
386 1.1 mrg return;
387 1.1 mrg }
388 1.1 mrg }
389 1.1 mrg }
390