Coverage Report

Created: 2026-09-28 06:58

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