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