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