remove.c revision 1.1.1.3 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.3 mrg Copyright 2009, 2012-2014 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.h"
39 1.1 mrg #include "gmp-impl.h"
40 1.1 mrg
41 1.1 mrg #if GMP_LIMB_BITS > 50
42 1.1 mrg #define LOG 50
43 1.1 mrg #else
44 1.1 mrg #define LOG GMP_LIMB_BITS
45 1.1 mrg #endif
46 1.1 mrg
47 1.1 mrg
48 1.1 mrg /* Input: U = {up,un}, V = {vp,vn} must be odd, cap
49 1.1 mrg Ouput W = {wp,*wn} allocation need is exactly *wn
50 1.1 mrg
51 1.1 mrg Set W = U / V^k, where k is the largest integer <= cap such that the
52 1.1 mrg division yields an integer.
53 1.1 mrg
54 1.1 mrg FIXME: We currently allow any operand overlap. This is quite non mpn-ish
55 1.1 mrg and might be changed, since it cost significant temporary space.
56 1.1.1.3 mrg * If we require W to have space for un + 1 limbs, we could save qp or qp2
57 1.1.1.3 mrg (but we will still need to copy things into wp 50% of the time).
58 1.1.1.3 mrg * If we allow ourselves to clobber U, we could save the other of qp and qp2,
59 1.1.1.3 mrg and the initial COPY (but also here we would need un + 1 limbs).
60 1.1 mrg */
61 1.1 mrg
62 1.1.1.2 mrg /* FIXME: We need to wrap mpn_bdiv_qr due to the itch interface. This need
63 1.1.1.2 mrg indicates a flaw in the current itch mechanism: Which operands not greater
64 1.1.1.2 mrg than un,un will incur the worst itch? We need a parallel foo_maxitch set
65 1.1.1.2 mrg of functions. */
66 1.1.1.2 mrg static void
67 1.1.1.2 mrg mpn_bdiv_qr_wrap (mp_ptr qp, mp_ptr rp,
68 1.1.1.2 mrg mp_srcptr np, mp_size_t nn,
69 1.1.1.2 mrg mp_srcptr dp, mp_size_t dn)
70 1.1.1.2 mrg {
71 1.1.1.2 mrg mp_ptr scratch_out;
72 1.1.1.2 mrg TMP_DECL;
73 1.1.1.2 mrg
74 1.1.1.2 mrg TMP_MARK;
75 1.1.1.2 mrg scratch_out = TMP_ALLOC_LIMBS (mpn_bdiv_qr_itch (nn, dn));
76 1.1.1.2 mrg mpn_bdiv_qr (qp, rp, np, nn, dp, dn, scratch_out);
77 1.1.1.2 mrg
78 1.1.1.2 mrg TMP_FREE;
79 1.1.1.2 mrg }
80 1.1.1.2 mrg
81 1.1 mrg mp_bitcnt_t
82 1.1 mrg mpn_remove (mp_ptr wp, mp_size_t *wn,
83 1.1.1.3 mrg mp_srcptr up, mp_size_t un, mp_srcptr vp, mp_size_t vn,
84 1.1 mrg mp_bitcnt_t cap)
85 1.1 mrg {
86 1.1.1.3 mrg mp_srcptr pwpsp[LOG];
87 1.1 mrg mp_size_t pwpsn[LOG];
88 1.1 mrg mp_size_t npowers;
89 1.1.1.3 mrg mp_ptr tp, qp, np, qp2;
90 1.1.1.3 mrg mp_srcptr pp;
91 1.1 mrg mp_size_t pn, nn, qn, i;
92 1.1 mrg mp_bitcnt_t pwr;
93 1.1 mrg TMP_DECL;
94 1.1 mrg
95 1.1 mrg ASSERT (un > 0);
96 1.1 mrg ASSERT (vn > 0);
97 1.1 mrg ASSERT (vp[0] % 2 != 0); /* 2-adic division wants odd numbers */
98 1.1 mrg ASSERT (vn > 1 || vp[0] > 1); /* else we would loop indefinitely */
99 1.1 mrg
100 1.1 mrg TMP_MARK;
101 1.1 mrg
102 1.1.1.3 mrg TMP_ALLOC_LIMBS_3 (qp, un + 1, /* quotient, alternating */
103 1.1.1.3 mrg qp2, un + 1, /* quotient, alternating */
104 1.1.1.3 mrg tp, (un + 1 + vn) / 2); /* remainder */
105 1.1 mrg pp = vp;
106 1.1 mrg pn = vn;
107 1.1 mrg
108 1.1 mrg MPN_COPY (qp, up, un);
109 1.1 mrg qn = un;
110 1.1 mrg
111 1.1 mrg npowers = 0;
112 1.1 mrg while (qn >= pn)
113 1.1 mrg {
114 1.1.1.2 mrg qp[qn] = 0;
115 1.1.1.2 mrg mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pp, pn);
116 1.1 mrg if (!mpn_zero_p (tp, pn))
117 1.1 mrg break; /* could not divide by V^npowers */
118 1.1 mrg
119 1.1 mrg MP_PTR_SWAP (qp, qp2);
120 1.1 mrg qn = qn - pn;
121 1.1 mrg qn += qp[qn] != 0;
122 1.1 mrg
123 1.1 mrg pwpsp[npowers] = pp;
124 1.1 mrg pwpsn[npowers] = pn;
125 1.1.1.3 mrg ++npowers;
126 1.1 mrg
127 1.1 mrg if (((mp_bitcnt_t) 2 << npowers) - 1 > cap)
128 1.1 mrg break;
129 1.1 mrg
130 1.1.1.2 mrg nn = 2 * pn - 1; /* next power will be at least this large */
131 1.1 mrg if (nn > qn)
132 1.1 mrg break; /* next power would be overlarge */
133 1.1 mrg
134 1.1.1.3 mrg if (npowers == 1) /* Alloc once, but only if it's needed */
135 1.1.1.3 mrg np = TMP_ALLOC_LIMBS (qn + LOG); /* powers of V */
136 1.1.1.3 mrg else
137 1.1.1.3 mrg np += pn;
138 1.1.1.3 mrg
139 1.1 mrg mpn_sqr (np, pp, pn);
140 1.1.1.3 mrg pn = nn + (np[nn] != 0);
141 1.1 mrg pp = np;
142 1.1 mrg }
143 1.1 mrg
144 1.1 mrg pwr = ((mp_bitcnt_t) 1 << npowers) - 1;
145 1.1 mrg
146 1.1.1.3 mrg for (i = npowers; --i >= 0;)
147 1.1 mrg {
148 1.1 mrg pn = pwpsn[i];
149 1.1 mrg if (qn < pn)
150 1.1 mrg continue;
151 1.1 mrg
152 1.1 mrg if (pwr + ((mp_bitcnt_t) 1 << i) > cap)
153 1.1 mrg continue; /* V^i would bring us past cap */
154 1.1 mrg
155 1.1.1.2 mrg qp[qn] = 0;
156 1.1.1.3 mrg mpn_bdiv_qr_wrap (qp2, tp, qp, qn + 1, pwpsp[i], pn);
157 1.1 mrg if (!mpn_zero_p (tp, pn))
158 1.1 mrg continue; /* could not divide by V^i */
159 1.1 mrg
160 1.1 mrg MP_PTR_SWAP (qp, qp2);
161 1.1 mrg qn = qn - pn;
162 1.1 mrg qn += qp[qn] != 0;
163 1.1 mrg
164 1.1 mrg pwr += (mp_bitcnt_t) 1 << i;
165 1.1 mrg }
166 1.1 mrg
167 1.1 mrg MPN_COPY (wp, qp, qn);
168 1.1 mrg *wn = qn;
169 1.1 mrg
170 1.1 mrg TMP_FREE;
171 1.1 mrg
172 1.1 mrg return pwr;
173 1.1 mrg }
174