1 /* __mpn_divmod -- Divide natural numbers, producing both remainder and
4 Copyright (C) 1993, 1994 Free Software Foundation, Inc.
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Library General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
16 License for more details.
18 You should have received a copy of the GNU Library General Public License
19 along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
26 /* Divide num (NUM_PTR/NUM_SIZE) by den (DEN_PTR/DEN_SIZE) and write
27 the NUM_SIZE-DEN_SIZE least significant quotient limbs at QUOT_PTR
28 and the DEN_SIZE long remainder at NUM_PTR.
29 Return the most significant limb of the quotient, this is always 0 or 1.
32 1. The most significant bit of the divisor must be set.
33 2. QUOT_PTR must either not overlap with the input operands at all, or
34 QUOT_PTR + DEN_SIZE >= NUM_PTR must hold true. (This means that it's
35 possible to put the quotient in the high part of NUM, right after the
40 __mpn_divmod (mp_ptr quot_ptr
,
41 mp_ptr num_ptr
, mp_size_t num_size
,
42 mp_srcptr den_ptr
, mp_size_t den_size
)
44 __mpn_divmod (quot_ptr
, num_ptr
, num_size
, den_ptr
, den_size
)
52 mp_limb most_significant_q_limb
= 0;
57 /* We are asked to divide by zero, so go ahead and do it! (To make
58 the compiler not remove this statement, return the value.) */
68 n1
= num_ptr
[num_size
- 1];
72 most_significant_q_limb
= 1;
76 for (i
= num_size
- 2; i
>= 0; i
--)
79 udiv_qrnnd (quot_ptr
[i
], n1
, n1
, n0
, d
);
92 num_ptr
+= num_size
- 2;
98 if (n1
>= d1
&& (n1
> d1
|| n0
>= d0
))
100 most_significant_q_limb
= 1;
101 sub_ddmmss (n1
, n0
, n1
, n0
, d1
, d0
);
104 for (i
= num_size
- den_size
- 1; i
>= 0; i
--)
112 /* Q should be either 111..111 or 111..110. Need special
113 treatment of this rare case as normal division would
118 if (r
< d1
) /* Carry in the addition? */
120 add_ssaaaa (n1
, n0
, r
- d0
, num_ptr
[0], 0, d0
);
129 udiv_qrnnd (q
, r
, n1
, n0
, d1
);
130 umul_ppmm (n1
, n0
, d0
, q
);
135 if (n1
> r
|| (n1
== r
&& n0
> n2
))
137 /* The estimated Q was too large. */
140 sub_ddmmss (n1
, n0
, n1
, n0
, 0, d0
);
142 if (r
>= d1
) /* If not carry, test Q again. */
147 sub_ddmmss (n1
, n0
, r
, n2
, n1
, n0
);
168 || __mpn_cmp (num_ptr
- den_size
, den_ptr
- den_size
,
171 __mpn_sub_n (num_ptr
- den_size
,
172 num_ptr
- den_size
, den_ptr
- den_size
,
174 most_significant_q_limb
= 1;
180 for (i
= num_size
- den_size
- 1; i
>= 0; i
--)
188 /* This might over-estimate q, but it's probably not worth
189 the extra code here to find out. */
195 udiv_qrnnd (q
, r
, n0
, num_ptr
[-1], dX
);
196 umul_ppmm (n1
, n0
, d1
, q
);
198 while (n1
> r
|| (n1
== r
&& n0
> num_ptr
[-2]))
202 if (r
< dX
) /* I.e. "carry in previous addition?" */
209 /* Possible optimization: We already have (q * n0) and (1 * n1)
210 after the calculation of q. Taking advantage of that, we
211 could make this loop make two iterations less. */
213 cy_limb
= __mpn_submul_1 (num_ptr
- den_size
,
214 den_ptr
- den_size
, den_size
, q
);
216 if (num_ptr
[0] != cy_limb
)
219 cy
= __mpn_add_n (num_ptr
- den_size
,
221 den_ptr
- den_size
, den_size
);
233 return most_significant_q_limb
;