remove.c revision 1.1.1.4 1 1.1 mrg /* mpn_remove -- divide out all multiples of odd mpn number from another mpn
2 1.1 mrg number.
3 1.1 mrg
4 1.1 mrg Contributed to the GNU project by Torbjorn Granlund.
5 1.1 mrg
6 1.1 mrg THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE. IT IS ONLY
7 1.1 mrg SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST
8 1.1 mrg GUARANTEED THAT IT WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE.
9 1.1 mrg
10 1.1.1.4 mrg Copyright 2009, 2012-2014, 2017 Free Software Foundation, Inc.
11 1.1 mrg
12 1.1 mrg This file is part of the GNU MP Library.
13 1.1 mrg
14 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify
15 1.1.1.3 mrg it under the terms of either:
16 1.1.1.3 mrg
17 1.1.1.3 mrg * the GNU Lesser General Public License as published by the Free
18 1.1.1.3 mrg Software Foundation; either version 3 of the License, or (at your
19 1.1.1.3 mrg option) any later version.
20 1.1.1.3 mrg
21 1.1.1.3 mrg or
22 1.1.1.3 mrg
23 1.1.1.3 mrg * the GNU General Public License as published by the Free Software
24 1.1.1.3 mrg Foundation; either version 2 of the License, or (at your option) any
25 1.1.1.3 mrg later version.
26 1.1.1.3 mrg
27 1.1.1.3 mrg or both in parallel, as here.
28 1.1 mrg
29 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
30 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31 1.1.1.3 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32 1.1.1.3 mrg for more details.
33 1.1 mrg
34 1.1.1.3 mrg You should have received copies of the GNU General Public License and the
35 1.1.1.3 mrg GNU Lesser General Public License along with the GNU MP Library. If not,
36 1.1.1.3 mrg see https://www.gnu.org/licenses/. */
37 1.1 mrg
38 1.1 mrg #include "gmp-impl.h"
39 1.1 mrg
40 1.1 mrg #if GMP_LIMB_BITS > 50
41 1.1 mrg #define LOG 50
42 1.1 mrg #else
43 1.1 mrg #define LOG GMP_LIMB_BITS
44 1.1 mrg #endif
45 1.1 mrg
46 1.1 mrg
47 1.1 mrg /* Input: U = {up,un}, V = {vp,vn} must be odd, cap
48 1.1 mrg Ouput W = {wp,*wn} allocation need is exactly *wn
49 1.1 mrg
50 1.1 mrg Set W = U / V^k, where k is the largest integer <= cap such that the
51 1.1 mrg division yields an integer.
52 1.1 mrg
53 1.1 mrg FIXME: We currently allow any operand overlap. This is quite non mpn-ish
54 1.1 mrg and might be changed, since it cost significant temporary space.
55 1.1.1.3 mrg * If we require W to have space for un + 1 limbs, we could save qp or qp2
56 1.1.1.3 mrg (but we will still need to copy things into wp 50% of the time).
57 1.1.1.3 mrg * If we allow ourselves to clobber U, we could save the other of qp and qp2,
58 1.1.1.3 mrg and the initial COPY (but also here we would need un + 1 limbs).
59 1.1 mrg */
60 1.1 mrg
61 1.1.1.2 mrg /* FIXME: We need to wrap mpn_bdiv_qr due to the itch interface. This need
62 1.1.1.2 mrg indicates a flaw in the current itch mechanism: Which operands not greater
63 1.1.1.2 mrg than un,un will incur the worst itch? We need a parallel foo_maxitch set
64 1.1.1.2 mrg of functions. */
65 1.1.1.2 mrg static void
66 1.1.1.2 mrg mpn_bdiv_qr_wrap (mp_ptr qp, mp_ptr rp,
67 1.1.1.2 mrg mp_srcptr np, mp_size_t nn,
68 1.1.1.2 mrg mp_srcptr dp, mp_size_t dn)
69 1.1.1.2 mrg {
70 1.1.1.2 mrg mp_ptr scratch_out;
71 1.1.1.2 mrg TMP_DECL;
72 1.1.1.2 mrg
73 1.1.1.2 mrg TMP_MARK;
74 1.1.1.2 mrg scratch_out = TMP_ALLOC_LIMBS (mpn_bdiv_qr_itch (nn, dn));
75 1.1.1.2 mrg mpn_bdiv_qr (qp, rp, np, nn, dp, dn, scratch_out);
76 1.1.1.2 mrg
77 1.1.1.2 mrg TMP_FREE;
78 1.1.1.2 mrg }
79 1.1.1.2 mrg
80 1.1 mrg mp_bitcnt_t
81 1.1 mrg mpn_remove (mp_ptr wp, mp_size_t *wn,
82 1.1.1.3 mrg mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn,
83 1.1 mrg mp_bitcnt_t cap)
84 1.1 mrg {
85 1.1.1.3 mrg mp_srcptr pwpsp[LOG];
86 1.1 mrg mp_size_t pwpsn[LOG];
87 1.1 mrg mp_size_t npowers;
88 1.1.1.3 mrg mp_ptr tp, qp, np, qp2;
89 1.1.1.3 mrg mp_srcptr pp;
90 1.1 mrg mp_size_t pn, nn, qn, i;
91 1.1 mrg mp_bitcnt_t pwr;
92 1.1 mrg TMP_DECL;
93 1.1 mrg
94 1.1 mrg ASSERT (un > 0);
95 1.1 mrg ASSERT (vn > 0);
96 1.1 mrg ASSERT (vp[0] % 2 != 0); /* 2-adic division wants odd numbers */
97 1.1 mrg ASSERT (vn > 1 || vp[0] > 1); /* else we would loop indefinitely */
98 1.1 mrg
99 1.1 mrg TMP_MARK;
100 1.1 mrg
101 1.1.1.3 mrg TMP_ALLOC_LIMBS_3 (qp, un + 1, /* quotient, alternating */
102 1.1.1.3 mrg qp2, un + 1, /* quotient, alternating */
103 1.1.1.3 mrg tp, (un + 1 + vn) / 2); /* remainder */
104 1.1 mrg pp = vp;
105 1.1 mrg pn = vn;
106 1.1 mrg
107 1.1 mrg MPN_COPY (qp, up, un);
108 1.1 mrg qn = un;
109 1.1 mrg
110 1.1 mrg npowers = 0;
111 1.1 mrg while (qn >= pn)
112 1.1 mrg {
113 1.1.1.2 mrg qp[qn] = 0;
114 1.1.1.2 mrg mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pp, pn);
115 1.1 mrg if (!mpn_zero_p (tp, pn))
116 1.1.1.4 mrg {
117 1.1.1.4 mrg if (mpn_cmp (tp, pp, pn) != 0)
118 1.1.1.4 mrg break; /* could not divide by V^npowers */
119 1.1.1.4 mrg }
120 1.1 mrg
121 1.1 mrg MP_PTR_SWAP (qp, qp2);
122 1.1 mrg qn = qn - pn;
123 1.1.1.4 mrg mpn_neg (qp, qp, qn+1);
124 1.1.1.4 mrg
125 1.1 mrg qn += qp[qn] != 0;
126 1.1 mrg
127 1.1 mrg pwpsp[npowers] = pp;
128 1.1 mrg pwpsn[npowers] = pn;
129 1.1.1.3 mrg ++npowers;
130 1.1 mrg
131 1.1 mrg if (((mp_bitcnt_t) 2 << npowers) - 1 > cap)
132 1.1 mrg break;
133 1.1 mrg
134 1.1.1.2 mrg nn = 2 * pn - 1; /* next power will be at least this large */
135 1.1 mrg if (nn > qn)
136 1.1 mrg break; /* next power would be overlarge */
137 1.1 mrg
138 1.1.1.3 mrg if (npowers == 1) /* Alloc once, but only if it's needed */
139 1.1.1.3 mrg np = TMP_ALLOC_LIMBS (qn + LOG); /* powers of V */
140 1.1.1.3 mrg else
141 1.1.1.3 mrg np += pn;
142 1.1.1.3 mrg
143 1.1 mrg mpn_sqr (np, pp, pn);
144 1.1.1.3 mrg pn = nn + (np[nn] != 0);
145 1.1 mrg pp = np;
146 1.1 mrg }
147 1.1 mrg
148 1.1 mrg pwr = ((mp_bitcnt_t) 1 << npowers) - 1;
149 1.1 mrg
150 1.1.1.3 mrg for (i = npowers; --i >= 0;)
151 1.1 mrg {
152 1.1 mrg pn = pwpsn[i];
153 1.1 mrg if (qn < pn)
154 1.1 mrg continue;
155 1.1 mrg
156 1.1 mrg if (pwr + ((mp_bitcnt_t) 1 << i) > cap)
157 1.1 mrg continue; /* V^i would bring us past cap */
158 1.1 mrg
159 1.1.1.2 mrg qp[qn] = 0;
160 1.1.1.3 mrg mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pwpsp[i], pn);
161 1.1 mrg if (!mpn_zero_p (tp, pn))
162 1.1.1.4 mrg {
163 1.1.1.4 mrg if (mpn_cmp (tp, pwpsp[i], pn) != 0)
164 1.1.1.4 mrg continue; /* could not divide by V^i */
165 1.1.1.4 mrg }
166 1.1 mrg
167 1.1 mrg MP_PTR_SWAP (qp, qp2);
168 1.1 mrg qn = qn - pn;
169 1.1.1.4 mrg mpn_neg (qp, qp, qn+1);
170 1.1.1.4 mrg
171 1.1 mrg qn += qp[qn] != 0;
172 1.1 mrg
173 1.1 mrg pwr += (mp_bitcnt_t) 1 << i;
174 1.1 mrg }
175 1.1 mrg
176 1.1 mrg MPN_COPY (wp, qp, qn);
177 1.1 mrg *wn = qn;
178 1.1 mrg
179 1.1 mrg TMP_FREE;
180 1.1 mrg
181 1.1 mrg return pwr;
182 1.1 mrg }
183