Line | Count | Source (jump to first uncovered line) |
1 | | /* mpn_divrem_2 -- Divide natural numbers, producing both remainder and |
2 | | quotient. The divisor is two limbs. |
3 | | |
4 | | THIS FILE CONTAINS INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. IT IS ONLY |
5 | | SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST |
6 | | GUARANTEED THAT THEY'LL CHANGE OR DISAPPEAR IN A FUTURE GNU MP RELEASE. |
7 | | |
8 | | |
9 | | Copyright 1993-1996, 1999-2002 Free Software Foundation, Inc. |
10 | | |
11 | | This file is part of the GNU MP Library. |
12 | | |
13 | | The GNU MP Library is free software; you can redistribute it and/or modify |
14 | | it under the terms of either: |
15 | | |
16 | | * the GNU Lesser General Public License as published by the Free |
17 | | Software Foundation; either version 3 of the License, or (at your |
18 | | option) any later version. |
19 | | |
20 | | or |
21 | | |
22 | | * the GNU General Public License as published by the Free Software |
23 | | Foundation; either version 2 of the License, or (at your option) any |
24 | | later version. |
25 | | |
26 | | or both in parallel, as here. |
27 | | |
28 | | The GNU MP Library is distributed in the hope that it will be useful, but |
29 | | WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
30 | | or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
31 | | for more details. |
32 | | |
33 | | You should have received copies of the GNU General Public License and the |
34 | | GNU Lesser General Public License along with the GNU MP Library. If not, |
35 | | see https://www.gnu.org/licenses/. */ |
36 | | |
37 | | #include "gmp-impl.h" |
38 | | #include "longlong.h" |
39 | | |
40 | | |
41 | | /* Divide num {np,nn} by den {dp,2} and write the nn-2 least significant |
42 | | quotient limbs at qp and the 2 long remainder at np. If qxn is non-zero, |
43 | | generate that many fraction bits and append them after the other quotient |
44 | | limbs. Return the most significant limb of the quotient, this is always 0 |
45 | | or 1. |
46 | | |
47 | | Preconditions: |
48 | | 1. The most significant bit of the divisor must be set. |
49 | | 2. qp must either not overlap with the input operands at all, or |
50 | | qp >= np + 2 must hold true. (This means that it's possible to put |
51 | | the quotient in the high part of {np,nn}, right above the remainder. |
52 | | 3. nn >= 2, even if qxn is non-zero. */ |
53 | | |
54 | | mp_limb_t |
55 | | mpn_divrem_2 (mp_ptr qp, mp_size_t qxn, |
56 | | mp_ptr np, mp_size_t nn, |
57 | | mp_srcptr dp) |
58 | 491 | { |
59 | 491 | mp_limb_t most_significant_q_limb; |
60 | 491 | mp_size_t i; |
61 | 491 | mp_limb_t r1, r0, d1, d0; |
62 | 491 | gmp_pi1_t di; |
63 | | |
64 | 491 | ASSERT (nn >= 2); |
65 | 491 | ASSERT (qxn >= 0); |
66 | 491 | ASSERT (dp[1] & GMP_NUMB_HIGHBIT); |
67 | 491 | ASSERT (! MPN_OVERLAP_P (qp, nn-2+qxn, np, nn) || qp >= np+2); |
68 | 491 | ASSERT_MPN (np, nn); |
69 | 491 | ASSERT_MPN (dp, 2); |
70 | | |
71 | 491 | np += nn - 2; |
72 | 491 | d1 = dp[1]; |
73 | 491 | d0 = dp[0]; |
74 | 491 | r1 = np[1]; |
75 | 491 | r0 = np[0]; |
76 | | |
77 | 491 | most_significant_q_limb = 0; |
78 | 491 | if (r1 >= d1 && (r1 > d1 || r0 >= d0)) |
79 | 0 | { |
80 | 0 | #if GMP_NAIL_BITS == 0 |
81 | 0 | sub_ddmmss (r1, r0, r1, r0, d1, d0); |
82 | | #else |
83 | | r0 = r0 - d0; |
84 | | r1 = r1 - d1 - (r0 >> GMP_LIMB_BITS - 1); |
85 | | r0 &= GMP_NUMB_MASK; |
86 | | #endif |
87 | 0 | most_significant_q_limb = 1; |
88 | 0 | } |
89 | | |
90 | 491 | invert_pi1 (di, d1, d0); |
91 | | |
92 | 491 | qp += qxn; |
93 | | |
94 | 1.47k | for (i = nn - 2 - 1; i >= 0; i--) |
95 | 982 | { |
96 | 982 | mp_limb_t n0, q; |
97 | 982 | n0 = np[-1]; |
98 | 982 | udiv_qr_3by2 (q, r1, r0, r1, r0, n0, d1, d0, di.inv32); |
99 | 982 | np--; |
100 | 982 | qp[i] = q; |
101 | 982 | } |
102 | | |
103 | 491 | if (UNLIKELY (qxn != 0)) |
104 | 0 | { |
105 | 0 | qp -= qxn; |
106 | 0 | for (i = qxn - 1; i >= 0; i--) |
107 | 0 | { |
108 | 0 | mp_limb_t q; |
109 | 0 | udiv_qr_3by2 (q, r1, r0, r1, r0, CNST_LIMB(0), d1, d0, di.inv32); |
110 | 0 | qp[i] = q; |
111 | 0 | } |
112 | 0 | } |
113 | | |
114 | 491 | np[1] = r1; |
115 | 491 | np[0] = r0; |
116 | | |
117 | 491 | return most_significant_q_limb; |
118 | 491 | } |