ยปCore Development>Code coverage>Modules/_decimal/libmpdec/basearith.c

Python code coverage for Modules/_decimal/libmpdec/basearith.c

#countcontent
1n/a/*
2n/a * Copyright (c) 2008-2016 Stefan Krah. All rights reserved.
3n/a *
4n/a * Redistribution and use in source and binary forms, with or without
5n/a * modification, are permitted provided that the following conditions
6n/a * are met:
7n/a *
8n/a * 1. Redistributions of source code must retain the above copyright
9n/a * notice, this list of conditions and the following disclaimer.
10n/a *
11n/a * 2. Redistributions in binary form must reproduce the above copyright
12n/a * notice, this list of conditions and the following disclaimer in the
13n/a * documentation and/or other materials provided with the distribution.
14n/a *
15n/a * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
16n/a * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17n/a * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18n/a * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19n/a * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20n/a * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21n/a * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22n/a * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23n/a * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24n/a * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25n/a * SUCH DAMAGE.
26n/a */
27n/a
28n/a
29n/a#include "mpdecimal.h"
30n/a#include <stdio.h>
31n/a#include <stdlib.h>
32n/a#include <string.h>
33n/a#include <assert.h>
34n/a#include "constants.h"
35n/a#include "typearith.h"
36n/a#include "basearith.h"
37n/a
38n/a
39n/a/*********************************************************************/
40n/a/* Calculations in base MPD_RADIX */
41n/a/*********************************************************************/
42n/a
43n/a
44n/a/*
45n/a * Knuth, TAOCP, Volume 2, 4.3.1:
46n/a * w := sum of u (len m) and v (len n)
47n/a * n > 0 and m >= n
48n/a * The calling function has to handle a possible final carry.
49n/a */
50n/ampd_uint_t
51n/a_mpd_baseadd(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
52n/a mpd_size_t m, mpd_size_t n)
53n/a{
54n/a mpd_uint_t s;
55n/a mpd_uint_t carry = 0;
56n/a mpd_size_t i;
57n/a
58n/a assert(n > 0 && m >= n);
59n/a
60n/a /* add n members of u and v */
61n/a for (i = 0; i < n; i++) {
62n/a s = u[i] + (v[i] + carry);
63n/a carry = (s < u[i]) | (s >= MPD_RADIX);
64n/a w[i] = carry ? s-MPD_RADIX : s;
65n/a }
66n/a /* if there is a carry, propagate it */
67n/a for (; carry && i < m; i++) {
68n/a s = u[i] + carry;
69n/a carry = (s == MPD_RADIX);
70n/a w[i] = carry ? 0 : s;
71n/a }
72n/a /* copy the rest of u */
73n/a for (; i < m; i++) {
74n/a w[i] = u[i];
75n/a }
76n/a
77n/a return carry;
78n/a}
79n/a
80n/a/*
81n/a * Add the contents of u to w. Carries are propagated further. The caller
82n/a * has to make sure that w is big enough.
83n/a */
84n/avoid
85n/a_mpd_baseaddto(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n)
86n/a{
87n/a mpd_uint_t s;
88n/a mpd_uint_t carry = 0;
89n/a mpd_size_t i;
90n/a
91n/a if (n == 0) return;
92n/a
93n/a /* add n members of u to w */
94n/a for (i = 0; i < n; i++) {
95n/a s = w[i] + (u[i] + carry);
96n/a carry = (s < w[i]) | (s >= MPD_RADIX);
97n/a w[i] = carry ? s-MPD_RADIX : s;
98n/a }
99n/a /* if there is a carry, propagate it */
100n/a for (; carry; i++) {
101n/a s = w[i] + carry;
102n/a carry = (s == MPD_RADIX);
103n/a w[i] = carry ? 0 : s;
104n/a }
105n/a}
106n/a
107n/a/*
108n/a * Add v to w (len m). The calling function has to handle a possible
109n/a * final carry. Assumption: m > 0.
110n/a */
111n/ampd_uint_t
112n/a_mpd_shortadd(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v)
113n/a{
114n/a mpd_uint_t s;
115n/a mpd_uint_t carry;
116n/a mpd_size_t i;
117n/a
118n/a assert(m > 0);
119n/a
120n/a /* add v to w */
121n/a s = w[0] + v;
122n/a carry = (s < v) | (s >= MPD_RADIX);
123n/a w[0] = carry ? s-MPD_RADIX : s;
124n/a
125n/a /* if there is a carry, propagate it */
126n/a for (i = 1; carry && i < m; i++) {
127n/a s = w[i] + carry;
128n/a carry = (s == MPD_RADIX);
129n/a w[i] = carry ? 0 : s;
130n/a }
131n/a
132n/a return carry;
133n/a}
134n/a
135n/a/* Increment u. The calling function has to handle a possible carry. */
136n/ampd_uint_t
137n/a_mpd_baseincr(mpd_uint_t *u, mpd_size_t n)
138n/a{
139n/a mpd_uint_t s;
140n/a mpd_uint_t carry = 1;
141n/a mpd_size_t i;
142n/a
143n/a assert(n > 0);
144n/a
145n/a /* if there is a carry, propagate it */
146n/a for (i = 0; carry && i < n; i++) {
147n/a s = u[i] + carry;
148n/a carry = (s == MPD_RADIX);
149n/a u[i] = carry ? 0 : s;
150n/a }
151n/a
152n/a return carry;
153n/a}
154n/a
155n/a/*
156n/a * Knuth, TAOCP, Volume 2, 4.3.1:
157n/a * w := difference of u (len m) and v (len n).
158n/a * number in u >= number in v;
159n/a */
160n/avoid
161n/a_mpd_basesub(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
162n/a mpd_size_t m, mpd_size_t n)
163n/a{
164n/a mpd_uint_t d;
165n/a mpd_uint_t borrow = 0;
166n/a mpd_size_t i;
167n/a
168n/a assert(m > 0 && n > 0);
169n/a
170n/a /* subtract n members of v from u */
171n/a for (i = 0; i < n; i++) {
172n/a d = u[i] - (v[i] + borrow);
173n/a borrow = (u[i] < d);
174n/a w[i] = borrow ? d + MPD_RADIX : d;
175n/a }
176n/a /* if there is a borrow, propagate it */
177n/a for (; borrow && i < m; i++) {
178n/a d = u[i] - borrow;
179n/a borrow = (u[i] == 0);
180n/a w[i] = borrow ? MPD_RADIX-1 : d;
181n/a }
182n/a /* copy the rest of u */
183n/a for (; i < m; i++) {
184n/a w[i] = u[i];
185n/a }
186n/a}
187n/a
188n/a/*
189n/a * Subtract the contents of u from w. w is larger than u. Borrows are
190n/a * propagated further, but eventually w can absorb the final borrow.
191n/a */
192n/avoid
193n/a_mpd_basesubfrom(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n)
194n/a{
195n/a mpd_uint_t d;
196n/a mpd_uint_t borrow = 0;
197n/a mpd_size_t i;
198n/a
199n/a if (n == 0) return;
200n/a
201n/a /* subtract n members of u from w */
202n/a for (i = 0; i < n; i++) {
203n/a d = w[i] - (u[i] + borrow);
204n/a borrow = (w[i] < d);
205n/a w[i] = borrow ? d + MPD_RADIX : d;
206n/a }
207n/a /* if there is a borrow, propagate it */
208n/a for (; borrow; i++) {
209n/a d = w[i] - borrow;
210n/a borrow = (w[i] == 0);
211n/a w[i] = borrow ? MPD_RADIX-1 : d;
212n/a }
213n/a}
214n/a
215n/a/* w := product of u (len n) and v (single word) */
216n/avoid
217n/a_mpd_shortmul(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
218n/a{
219n/a mpd_uint_t hi, lo;
220n/a mpd_uint_t carry = 0;
221n/a mpd_size_t i;
222n/a
223n/a assert(n > 0);
224n/a
225n/a for (i=0; i < n; i++) {
226n/a
227n/a _mpd_mul_words(&hi, &lo, u[i], v);
228n/a lo = carry + lo;
229n/a if (lo < carry) hi++;
230n/a
231n/a _mpd_div_words_r(&carry, &w[i], hi, lo);
232n/a }
233n/a w[i] = carry;
234n/a}
235n/a
236n/a/*
237n/a * Knuth, TAOCP, Volume 2, 4.3.1:
238n/a * w := product of u (len m) and v (len n)
239n/a * w must be initialized to zero
240n/a */
241n/avoid
242n/a_mpd_basemul(mpd_uint_t *w, const mpd_uint_t *u, const mpd_uint_t *v,
243n/a mpd_size_t m, mpd_size_t n)
244n/a{
245n/a mpd_uint_t hi, lo;
246n/a mpd_uint_t carry;
247n/a mpd_size_t i, j;
248n/a
249n/a assert(m > 0 && n > 0);
250n/a
251n/a for (j=0; j < n; j++) {
252n/a carry = 0;
253n/a for (i=0; i < m; i++) {
254n/a
255n/a _mpd_mul_words(&hi, &lo, u[i], v[j]);
256n/a lo = w[i+j] + lo;
257n/a if (lo < w[i+j]) hi++;
258n/a lo = carry + lo;
259n/a if (lo < carry) hi++;
260n/a
261n/a _mpd_div_words_r(&carry, &w[i+j], hi, lo);
262n/a }
263n/a w[j+m] = carry;
264n/a }
265n/a}
266n/a
267n/a/*
268n/a * Knuth, TAOCP Volume 2, 4.3.1, exercise 16:
269n/a * w := quotient of u (len n) divided by a single word v
270n/a */
271n/ampd_uint_t
272n/a_mpd_shortdiv(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
273n/a{
274n/a mpd_uint_t hi, lo;
275n/a mpd_uint_t rem = 0;
276n/a mpd_size_t i;
277n/a
278n/a assert(n > 0);
279n/a
280n/a for (i=n-1; i != MPD_SIZE_MAX; i--) {
281n/a
282n/a _mpd_mul_words(&hi, &lo, rem, MPD_RADIX);
283n/a lo = u[i] + lo;
284n/a if (lo < u[i]) hi++;
285n/a
286n/a _mpd_div_words(&w[i], &rem, hi, lo, v);
287n/a }
288n/a
289n/a return rem;
290n/a}
291n/a
292n/a/*
293n/a * Knuth, TAOCP Volume 2, 4.3.1:
294n/a * q, r := quotient and remainder of uconst (len nplusm)
295n/a * divided by vconst (len n)
296n/a * nplusm >= n
297n/a *
298n/a * If r is not NULL, r will contain the remainder. If r is NULL, the
299n/a * return value indicates if there is a remainder: 1 for true, 0 for
300n/a * false. A return value of -1 indicates an error.
301n/a */
302n/aint
303n/a_mpd_basedivmod(mpd_uint_t *q, mpd_uint_t *r,
304n/a const mpd_uint_t *uconst, const mpd_uint_t *vconst,
305n/a mpd_size_t nplusm, mpd_size_t n)
306n/a{
307n/a mpd_uint_t ustatic[MPD_MINALLOC_MAX];
308n/a mpd_uint_t vstatic[MPD_MINALLOC_MAX];
309n/a mpd_uint_t *u = ustatic;
310n/a mpd_uint_t *v = vstatic;
311n/a mpd_uint_t d, qhat, rhat, w2[2];
312n/a mpd_uint_t hi, lo, x;
313n/a mpd_uint_t carry;
314n/a mpd_size_t i, j, m;
315n/a int retval = 0;
316n/a
317n/a assert(n > 1 && nplusm >= n);
318n/a m = sub_size_t(nplusm, n);
319n/a
320n/a /* D1: normalize */
321n/a d = MPD_RADIX / (vconst[n-1] + 1);
322n/a
323n/a if (nplusm >= MPD_MINALLOC_MAX) {
324n/a if ((u = mpd_alloc(nplusm+1, sizeof *u)) == NULL) {
325n/a return -1;
326n/a }
327n/a }
328n/a if (n >= MPD_MINALLOC_MAX) {
329n/a if ((v = mpd_alloc(n+1, sizeof *v)) == NULL) {
330n/a mpd_free(u);
331n/a return -1;
332n/a }
333n/a }
334n/a
335n/a _mpd_shortmul(u, uconst, nplusm, d);
336n/a _mpd_shortmul(v, vconst, n, d);
337n/a
338n/a /* D2: loop */
339n/a for (j=m; j != MPD_SIZE_MAX; j--) {
340n/a
341n/a /* D3: calculate qhat and rhat */
342n/a rhat = _mpd_shortdiv(w2, u+j+n-1, 2, v[n-1]);
343n/a qhat = w2[1] * MPD_RADIX + w2[0];
344n/a
345n/a while (1) {
346n/a if (qhat < MPD_RADIX) {
347n/a _mpd_singlemul(w2, qhat, v[n-2]);
348n/a if (w2[1] <= rhat) {
349n/a if (w2[1] != rhat || w2[0] <= u[j+n-2]) {
350n/a break;
351n/a }
352n/a }
353n/a }
354n/a qhat -= 1;
355n/a rhat += v[n-1];
356n/a if (rhat < v[n-1] || rhat >= MPD_RADIX) {
357n/a break;
358n/a }
359n/a }
360n/a /* D4: multiply and subtract */
361n/a carry = 0;
362n/a for (i=0; i <= n; i++) {
363n/a
364n/a _mpd_mul_words(&hi, &lo, qhat, v[i]);
365n/a
366n/a lo = carry + lo;
367n/a if (lo < carry) hi++;
368n/a
369n/a _mpd_div_words_r(&hi, &lo, hi, lo);
370n/a
371n/a x = u[i+j] - lo;
372n/a carry = (u[i+j] < x);
373n/a u[i+j] = carry ? x+MPD_RADIX : x;
374n/a carry += hi;
375n/a }
376n/a q[j] = qhat;
377n/a /* D5: test remainder */
378n/a if (carry) {
379n/a q[j] -= 1;
380n/a /* D6: add back */
381n/a (void)_mpd_baseadd(u+j, u+j, v, n+1, n);
382n/a }
383n/a }
384n/a
385n/a /* D8: unnormalize */
386n/a if (r != NULL) {
387n/a _mpd_shortdiv(r, u, n, d);
388n/a /* we are not interested in the return value here */
389n/a retval = 0;
390n/a }
391n/a else {
392n/a retval = !_mpd_isallzero(u, n);
393n/a }
394n/a
395n/a
396n/aif (u != ustatic) mpd_free(u);
397n/aif (v != vstatic) mpd_free(v);
398n/areturn retval;
399n/a}
400n/a
401n/a/*
402n/a * Left shift of src by 'shift' digits; src may equal dest.
403n/a *
404n/a * dest := area of n mpd_uint_t with space for srcdigits+shift digits.
405n/a * src := coefficient with length m.
406n/a *
407n/a * The case splits in the function are non-obvious. The following
408n/a * equations might help:
409n/a *
410n/a * Let msdigits denote the number of digits in the most significant
411n/a * word of src. Then 1 <= msdigits <= rdigits.
412n/a *
413n/a * 1) shift = q * rdigits + r
414n/a * 2) srcdigits = qsrc * rdigits + msdigits
415n/a * 3) destdigits = shift + srcdigits
416n/a * = q * rdigits + r + qsrc * rdigits + msdigits
417n/a * = q * rdigits + (qsrc * rdigits + (r + msdigits))
418n/a *
419n/a * The result has q zero words, followed by the coefficient that
420n/a * is left-shifted by r. The case r == 0 is trivial. For r > 0, it
421n/a * is important to keep in mind that we always read m source words,
422n/a * but write m+1 destination words if r + msdigits > rdigits, m words
423n/a * otherwise.
424n/a */
425n/avoid
426n/a_mpd_baseshiftl(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t n, mpd_size_t m,
427n/a mpd_size_t shift)
428n/a{
429n/a#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
430n/a /* spurious uninitialized warnings */
431n/a mpd_uint_t l=l, lprev=lprev, h=h;
432n/a#else
433n/a mpd_uint_t l, lprev, h;
434n/a#endif
435n/a mpd_uint_t q, r;
436n/a mpd_uint_t ph;
437n/a
438n/a assert(m > 0 && n >= m);
439n/a
440n/a _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);
441n/a
442n/a if (r != 0) {
443n/a
444n/a ph = mpd_pow10[r];
445n/a
446n/a --m; --n;
447n/a _mpd_divmod_pow10(&h, &lprev, src[m--], MPD_RDIGITS-r);
448n/a if (h != 0) { /* r + msdigits > rdigits <==> h != 0 */
449n/a dest[n--] = h;
450n/a }
451n/a /* write m-1 shifted words */
452n/a for (; m != MPD_SIZE_MAX; m--,n--) {
453n/a _mpd_divmod_pow10(&h, &l, src[m], MPD_RDIGITS-r);
454n/a dest[n] = ph * lprev + h;
455n/a lprev = l;
456n/a }
457n/a /* write least significant word */
458n/a dest[q] = ph * lprev;
459n/a }
460n/a else {
461n/a while (--m != MPD_SIZE_MAX) {
462n/a dest[m+q] = src[m];
463n/a }
464n/a }
465n/a
466n/a mpd_uint_zero(dest, q);
467n/a}
468n/a
469n/a/*
470n/a * Right shift of src by 'shift' digits; src may equal dest.
471n/a * Assumption: srcdigits-shift > 0.
472n/a *
473n/a * dest := area with space for srcdigits-shift digits.
474n/a * src := coefficient with length 'slen'.
475n/a *
476n/a * The case splits in the function rely on the following equations:
477n/a *
478n/a * Let msdigits denote the number of digits in the most significant
479n/a * word of src. Then 1 <= msdigits <= rdigits.
480n/a *
481n/a * 1) shift = q * rdigits + r
482n/a * 2) srcdigits = qsrc * rdigits + msdigits
483n/a * 3) destdigits = srcdigits - shift
484n/a * = qsrc * rdigits + msdigits - (q * rdigits + r)
485n/a * = (qsrc - q) * rdigits + msdigits - r
486n/a *
487n/a * Since destdigits > 0 and 1 <= msdigits <= rdigits:
488n/a *
489n/a * 4) qsrc >= q
490n/a * 5) qsrc == q ==> msdigits > r
491n/a *
492n/a * The result has slen-q words if msdigits > r, slen-q-1 words otherwise.
493n/a */
494n/ampd_uint_t
495n/a_mpd_baseshiftr(mpd_uint_t *dest, mpd_uint_t *src, mpd_size_t slen,
496n/a mpd_size_t shift)
497n/a{
498n/a#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
499n/a /* spurious uninitialized warnings */
500n/a mpd_uint_t l=l, h=h, hprev=hprev; /* low, high, previous high */
501n/a#else
502n/a mpd_uint_t l, h, hprev; /* low, high, previous high */
503n/a#endif
504n/a mpd_uint_t rnd, rest; /* rounding digit, rest */
505n/a mpd_uint_t q, r;
506n/a mpd_size_t i, j;
507n/a mpd_uint_t ph;
508n/a
509n/a assert(slen > 0);
510n/a
511n/a _mpd_div_word(&q, &r, (mpd_uint_t)shift, MPD_RDIGITS);
512n/a
513n/a rnd = rest = 0;
514n/a if (r != 0) {
515n/a
516n/a ph = mpd_pow10[MPD_RDIGITS-r];
517n/a
518n/a _mpd_divmod_pow10(&hprev, &rest, src[q], r);
519n/a _mpd_divmod_pow10(&rnd, &rest, rest, r-1);
520n/a
521n/a if (rest == 0 && q > 0) {
522n/a rest = !_mpd_isallzero(src, q);
523n/a }
524n/a /* write slen-q-1 words */
525n/a for (j=0,i=q+1; i<slen; i++,j++) {
526n/a _mpd_divmod_pow10(&h, &l, src[i], r);
527n/a dest[j] = ph * l + hprev;
528n/a hprev = h;
529n/a }
530n/a /* write most significant word */
531n/a if (hprev != 0) { /* always the case if slen==q-1 */
532n/a dest[j] = hprev;
533n/a }
534n/a }
535n/a else {
536n/a if (q > 0) {
537n/a _mpd_divmod_pow10(&rnd, &rest, src[q-1], MPD_RDIGITS-1);
538n/a /* is there any non-zero digit below rnd? */
539n/a if (rest == 0) rest = !_mpd_isallzero(src, q-1);
540n/a }
541n/a for (j = 0; j < slen-q; j++) {
542n/a dest[j] = src[q+j];
543n/a }
544n/a }
545n/a
546n/a /* 0-4 ==> rnd+rest < 0.5 */
547n/a /* 5 ==> rnd+rest == 0.5 */
548n/a /* 6-9 ==> rnd+rest > 0.5 */
549n/a return (rnd == 0 || rnd == 5) ? rnd + !!rest : rnd;
550n/a}
551n/a
552n/a
553n/a/*********************************************************************/
554n/a/* Calculations in base b */
555n/a/*********************************************************************/
556n/a
557n/a/*
558n/a * Add v to w (len m). The calling function has to handle a possible
559n/a * final carry. Assumption: m > 0.
560n/a */
561n/ampd_uint_t
562n/a_mpd_shortadd_b(mpd_uint_t *w, mpd_size_t m, mpd_uint_t v, mpd_uint_t b)
563n/a{
564n/a mpd_uint_t s;
565n/a mpd_uint_t carry;
566n/a mpd_size_t i;
567n/a
568n/a assert(m > 0);
569n/a
570n/a /* add v to w */
571n/a s = w[0] + v;
572n/a carry = (s < v) | (s >= b);
573n/a w[0] = carry ? s-b : s;
574n/a
575n/a /* if there is a carry, propagate it */
576n/a for (i = 1; carry && i < m; i++) {
577n/a s = w[i] + carry;
578n/a carry = (s == b);
579n/a w[i] = carry ? 0 : s;
580n/a }
581n/a
582n/a return carry;
583n/a}
584n/a
585n/a/* w := product of u (len n) and v (single word). Return carry. */
586n/ampd_uint_t
587n/a_mpd_shortmul_c(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n, mpd_uint_t v)
588n/a{
589n/a mpd_uint_t hi, lo;
590n/a mpd_uint_t carry = 0;
591n/a mpd_size_t i;
592n/a
593n/a assert(n > 0);
594n/a
595n/a for (i=0; i < n; i++) {
596n/a
597n/a _mpd_mul_words(&hi, &lo, u[i], v);
598n/a lo = carry + lo;
599n/a if (lo < carry) hi++;
600n/a
601n/a _mpd_div_words_r(&carry, &w[i], hi, lo);
602n/a }
603n/a
604n/a return carry;
605n/a}
606n/a
607n/a/* w := product of u (len n) and v (single word) */
608n/ampd_uint_t
609n/a_mpd_shortmul_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n,
610n/a mpd_uint_t v, mpd_uint_t b)
611n/a{
612n/a mpd_uint_t hi, lo;
613n/a mpd_uint_t carry = 0;
614n/a mpd_size_t i;
615n/a
616n/a assert(n > 0);
617n/a
618n/a for (i=0; i < n; i++) {
619n/a
620n/a _mpd_mul_words(&hi, &lo, u[i], v);
621n/a lo = carry + lo;
622n/a if (lo < carry) hi++;
623n/a
624n/a _mpd_div_words(&carry, &w[i], hi, lo, b);
625n/a }
626n/a
627n/a return carry;
628n/a}
629n/a
630n/a/*
631n/a * Knuth, TAOCP Volume 2, 4.3.1, exercise 16:
632n/a * w := quotient of u (len n) divided by a single word v
633n/a */
634n/ampd_uint_t
635n/a_mpd_shortdiv_b(mpd_uint_t *w, const mpd_uint_t *u, mpd_size_t n,
636n/a mpd_uint_t v, mpd_uint_t b)
637n/a{
638n/a mpd_uint_t hi, lo;
639n/a mpd_uint_t rem = 0;
640n/a mpd_size_t i;
641n/a
642n/a assert(n > 0);
643n/a
644n/a for (i=n-1; i != MPD_SIZE_MAX; i--) {
645n/a
646n/a _mpd_mul_words(&hi, &lo, rem, b);
647n/a lo = u[i] + lo;
648n/a if (lo < u[i]) hi++;
649n/a
650n/a _mpd_div_words(&w[i], &rem, hi, lo, v);
651n/a }
652n/a
653n/a return rem;
654n/a}
655n/a
656n/a
657n/a