github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mpn/generic/tdiv_qr.c (about) 1 /* mpn_tdiv_qr -- Divide the numerator (np,nn) by the denominator (dp,dn) and 2 write the nn-dn+1 quotient limbs at qp and the dn remainder limbs at rp. If 3 qxn is non-zero, generate that many fraction limbs and append them after the 4 other quotient limbs, and update the remainder accordingly. The input 5 operands are unaffected. 6 7 Preconditions: 8 1. The most significant limb of of the divisor must be non-zero. 9 2. nn >= dn, even if qxn is non-zero. (??? relax this ???) 10 11 The time complexity of this is O(qn*qn+M(dn,qn)), where M(m,n) is the time 12 complexity of multiplication. 13 14 Copyright 1997, 2000-2002, 2005, 2009 Free Software Foundation, Inc. 15 16 This file is part of the GNU MP Library. 17 18 The GNU MP Library is free software; you can redistribute it and/or modify 19 it under the terms of either: 20 21 * the GNU Lesser General Public License as published by the Free 22 Software Foundation; either version 3 of the License, or (at your 23 option) any later version. 24 25 or 26 27 * the GNU General Public License as published by the Free Software 28 Foundation; either version 2 of the License, or (at your option) any 29 later version. 30 31 or both in parallel, as here. 32 33 The GNU MP Library is distributed in the hope that it will be useful, but 34 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 35 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36 for more details. 37 38 You should have received copies of the GNU General Public License and the 39 GNU Lesser General Public License along with the GNU MP Library. If not, 40 see https://www.gnu.org/licenses/. */ 41 42 #include "gmp.h" 43 #include "gmp-impl.h" 44 #include "longlong.h" 45 46 47 void 48 mpn_tdiv_qr (mp_ptr qp, mp_ptr rp, mp_size_t qxn, 49 mp_srcptr np, mp_size_t nn, mp_srcptr dp, mp_size_t dn) 50 { 51 ASSERT_ALWAYS (qxn == 0); 52 53 ASSERT (nn >= 0); 54 ASSERT (dn >= 0); 55 ASSERT (dn == 0 || dp[dn - 1] != 0); 56 ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, np, nn)); 57 ASSERT (! MPN_OVERLAP_P (qp, nn - dn + 1 + qxn, dp, dn)); 58 59 switch (dn) 60 { 61 case 0: 62 DIVIDE_BY_ZERO; 63 64 case 1: 65 { 66 rp[0] = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, dp[0]); 67 return; 68 } 69 70 case 2: 71 { 72 mp_ptr n2p, d2p; 73 mp_limb_t qhl, cy; 74 TMP_DECL; 75 TMP_MARK; 76 if ((dp[1] & GMP_NUMB_HIGHBIT) == 0) 77 { 78 int cnt; 79 mp_limb_t dtmp[2]; 80 count_leading_zeros (cnt, dp[1]); 81 cnt -= GMP_NAIL_BITS; 82 d2p = dtmp; 83 d2p[1] = (dp[1] << cnt) | (dp[0] >> (GMP_NUMB_BITS - cnt)); 84 d2p[0] = (dp[0] << cnt) & GMP_NUMB_MASK; 85 n2p = TMP_ALLOC_LIMBS (nn + 1); 86 cy = mpn_lshift (n2p, np, nn, cnt); 87 n2p[nn] = cy; 88 qhl = mpn_divrem_2 (qp, 0L, n2p, nn + (cy != 0), d2p); 89 if (cy == 0) 90 qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */ 91 rp[0] = (n2p[0] >> cnt) 92 | ((n2p[1] << (GMP_NUMB_BITS - cnt)) & GMP_NUMB_MASK); 93 rp[1] = (n2p[1] >> cnt); 94 } 95 else 96 { 97 d2p = (mp_ptr) dp; 98 n2p = TMP_ALLOC_LIMBS (nn); 99 MPN_COPY (n2p, np, nn); 100 qhl = mpn_divrem_2 (qp, 0L, n2p, nn, d2p); 101 qp[nn - 2] = qhl; /* always store nn-2+1 quotient limbs */ 102 rp[0] = n2p[0]; 103 rp[1] = n2p[1]; 104 } 105 TMP_FREE; 106 return; 107 } 108 109 default: 110 { 111 int adjust; 112 gmp_pi1_t dinv; 113 TMP_DECL; 114 TMP_MARK; 115 adjust = np[nn - 1] >= dp[dn - 1]; /* conservative tests for quotient size */ 116 if (nn + adjust >= 2 * dn) 117 { 118 mp_ptr n2p, d2p; 119 mp_limb_t cy; 120 int cnt; 121 122 qp[nn - dn] = 0; /* zero high quotient limb */ 123 if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0) /* normalize divisor */ 124 { 125 count_leading_zeros (cnt, dp[dn - 1]); 126 cnt -= GMP_NAIL_BITS; 127 d2p = TMP_ALLOC_LIMBS (dn); 128 mpn_lshift (d2p, dp, dn, cnt); 129 n2p = TMP_ALLOC_LIMBS (nn + 1); 130 cy = mpn_lshift (n2p, np, nn, cnt); 131 n2p[nn] = cy; 132 nn += adjust; 133 } 134 else 135 { 136 cnt = 0; 137 d2p = (mp_ptr) dp; 138 n2p = TMP_ALLOC_LIMBS (nn + 1); 139 MPN_COPY (n2p, np, nn); 140 n2p[nn] = 0; 141 nn += adjust; 142 } 143 144 invert_pi1 (dinv, d2p[dn - 1], d2p[dn - 2]); 145 if (BELOW_THRESHOLD (dn, DC_DIV_QR_THRESHOLD)) 146 mpn_sbpi1_div_qr (qp, n2p, nn, d2p, dn, dinv.inv32); 147 else if (BELOW_THRESHOLD (dn, MUPI_DIV_QR_THRESHOLD) || /* fast condition */ 148 BELOW_THRESHOLD (nn, 2 * MU_DIV_QR_THRESHOLD) || /* fast condition */ 149 (double) (2 * (MU_DIV_QR_THRESHOLD - MUPI_DIV_QR_THRESHOLD)) * dn /* slow... */ 150 + (double) MUPI_DIV_QR_THRESHOLD * nn > (double) dn * nn) /* ...condition */ 151 mpn_dcpi1_div_qr (qp, n2p, nn, d2p, dn, &dinv); 152 else 153 { 154 mp_size_t itch = mpn_mu_div_qr_itch (nn, dn, 0); 155 mp_ptr scratch = TMP_ALLOC_LIMBS (itch); 156 mpn_mu_div_qr (qp, rp, n2p, nn, d2p, dn, scratch); 157 n2p = rp; 158 } 159 160 if (cnt != 0) 161 mpn_rshift (rp, n2p, dn, cnt); 162 else 163 MPN_COPY (rp, n2p, dn); 164 TMP_FREE; 165 return; 166 } 167 168 /* When we come here, the numerator/partial remainder is less 169 than twice the size of the denominator. */ 170 171 { 172 /* Problem: 173 174 Divide a numerator N with nn limbs by a denominator D with dn 175 limbs forming a quotient of qn=nn-dn+1 limbs. When qn is small 176 compared to dn, conventional division algorithms perform poorly. 177 We want an algorithm that has an expected running time that is 178 dependent only on qn. 179 180 Algorithm (very informally stated): 181 182 1) Divide the 2 x qn most significant limbs from the numerator 183 by the qn most significant limbs from the denominator. Call 184 the result qest. This is either the correct quotient, but 185 might be 1 or 2 too large. Compute the remainder from the 186 division. (This step is implemented by an mpn_divrem call.) 187 188 2) Is the most significant limb from the remainder < p, where p 189 is the product of the most significant limb from the quotient 190 and the next(d)? (Next(d) denotes the next ignored limb from 191 the denominator.) If it is, decrement qest, and adjust the 192 remainder accordingly. 193 194 3) Is the remainder >= qest? If it is, qest is the desired 195 quotient. The algorithm terminates. 196 197 4) Subtract qest x next(d) from the remainder. If there is 198 borrow out, decrement qest, and adjust the remainder 199 accordingly. 200 201 5) Skip one word from the denominator (i.e., let next(d) denote 202 the next less significant limb. */ 203 204 mp_size_t qn; 205 mp_ptr n2p, d2p; 206 mp_ptr tp; 207 mp_limb_t cy; 208 mp_size_t in, rn; 209 mp_limb_t quotient_too_large; 210 unsigned int cnt; 211 212 qn = nn - dn; 213 qp[qn] = 0; /* zero high quotient limb */ 214 qn += adjust; /* qn cannot become bigger */ 215 216 if (qn == 0) 217 { 218 MPN_COPY (rp, np, dn); 219 TMP_FREE; 220 return; 221 } 222 223 in = dn - qn; /* (at least partially) ignored # of limbs in ops */ 224 /* Normalize denominator by shifting it to the left such that its 225 most significant bit is set. Then shift the numerator the same 226 amount, to mathematically preserve quotient. */ 227 if ((dp[dn - 1] & GMP_NUMB_HIGHBIT) == 0) 228 { 229 count_leading_zeros (cnt, dp[dn - 1]); 230 cnt -= GMP_NAIL_BITS; 231 232 d2p = TMP_ALLOC_LIMBS (qn); 233 mpn_lshift (d2p, dp + in, qn, cnt); 234 d2p[0] |= dp[in - 1] >> (GMP_NUMB_BITS - cnt); 235 236 n2p = TMP_ALLOC_LIMBS (2 * qn + 1); 237 cy = mpn_lshift (n2p, np + nn - 2 * qn, 2 * qn, cnt); 238 if (adjust) 239 { 240 n2p[2 * qn] = cy; 241 n2p++; 242 } 243 else 244 { 245 n2p[0] |= np[nn - 2 * qn - 1] >> (GMP_NUMB_BITS - cnt); 246 } 247 } 248 else 249 { 250 cnt = 0; 251 d2p = (mp_ptr) dp + in; 252 253 n2p = TMP_ALLOC_LIMBS (2 * qn + 1); 254 MPN_COPY (n2p, np + nn - 2 * qn, 2 * qn); 255 if (adjust) 256 { 257 n2p[2 * qn] = 0; 258 n2p++; 259 } 260 } 261 262 /* Get an approximate quotient using the extracted operands. */ 263 if (qn == 1) 264 { 265 mp_limb_t q0, r0; 266 udiv_qrnnd (q0, r0, n2p[1], n2p[0] << GMP_NAIL_BITS, d2p[0] << GMP_NAIL_BITS); 267 n2p[0] = r0 >> GMP_NAIL_BITS; 268 qp[0] = q0; 269 } 270 else if (qn == 2) 271 mpn_divrem_2 (qp, 0L, n2p, 4L, d2p); /* FIXME: obsolete function */ 272 else 273 { 274 invert_pi1 (dinv, d2p[qn - 1], d2p[qn - 2]); 275 if (BELOW_THRESHOLD (qn, DC_DIV_QR_THRESHOLD)) 276 mpn_sbpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, dinv.inv32); 277 else if (BELOW_THRESHOLD (qn, MU_DIV_QR_THRESHOLD)) 278 mpn_dcpi1_div_qr (qp, n2p, 2 * qn, d2p, qn, &dinv); 279 else 280 { 281 mp_size_t itch = mpn_mu_div_qr_itch (2 * qn, qn, 0); 282 mp_ptr scratch = TMP_ALLOC_LIMBS (itch); 283 mp_ptr r2p = rp; 284 if (np == r2p) /* If N and R share space, put ... */ 285 r2p += nn - qn; /* intermediate remainder at N's upper end. */ 286 mpn_mu_div_qr (qp, r2p, n2p, 2 * qn, d2p, qn, scratch); 287 MPN_COPY (n2p, r2p, qn); 288 } 289 } 290 291 rn = qn; 292 /* Multiply the first ignored divisor limb by the most significant 293 quotient limb. If that product is > the partial remainder's 294 most significant limb, we know the quotient is too large. This 295 test quickly catches most cases where the quotient is too large; 296 it catches all cases where the quotient is 2 too large. */ 297 { 298 mp_limb_t dl, x; 299 mp_limb_t h, dummy; 300 301 if (in - 2 < 0) 302 dl = 0; 303 else 304 dl = dp[in - 2]; 305 306 #if GMP_NAIL_BITS == 0 307 x = (dp[in - 1] << cnt) | ((dl >> 1) >> ((~cnt) % GMP_LIMB_BITS)); 308 #else 309 x = (dp[in - 1] << cnt) & GMP_NUMB_MASK; 310 if (cnt != 0) 311 x |= dl >> (GMP_NUMB_BITS - cnt); 312 #endif 313 umul_ppmm (h, dummy, x, qp[qn - 1] << GMP_NAIL_BITS); 314 315 if (n2p[qn - 1] < h) 316 { 317 mp_limb_t cy; 318 319 mpn_decr_u (qp, (mp_limb_t) 1); 320 cy = mpn_add_n (n2p, n2p, d2p, qn); 321 if (cy) 322 { 323 /* The partial remainder is safely large. */ 324 n2p[qn] = cy; 325 ++rn; 326 } 327 } 328 } 329 330 quotient_too_large = 0; 331 if (cnt != 0) 332 { 333 mp_limb_t cy1, cy2; 334 335 /* Append partially used numerator limb to partial remainder. */ 336 cy1 = mpn_lshift (n2p, n2p, rn, GMP_NUMB_BITS - cnt); 337 n2p[0] |= np[in - 1] & (GMP_NUMB_MASK >> cnt); 338 339 /* Update partial remainder with partially used divisor limb. */ 340 cy2 = mpn_submul_1 (n2p, qp, qn, dp[in - 1] & (GMP_NUMB_MASK >> cnt)); 341 if (qn != rn) 342 { 343 ASSERT_ALWAYS (n2p[qn] >= cy2); 344 n2p[qn] -= cy2; 345 } 346 else 347 { 348 n2p[qn] = cy1 - cy2; /* & GMP_NUMB_MASK; */ 349 350 quotient_too_large = (cy1 < cy2); 351 ++rn; 352 } 353 --in; 354 } 355 /* True: partial remainder now is neutral, i.e., it is not shifted up. */ 356 357 tp = TMP_ALLOC_LIMBS (dn); 358 359 if (in < qn) 360 { 361 if (in == 0) 362 { 363 MPN_COPY (rp, n2p, rn); 364 ASSERT_ALWAYS (rn == dn); 365 goto foo; 366 } 367 mpn_mul (tp, qp, qn, dp, in); 368 } 369 else 370 mpn_mul (tp, dp, in, qp, qn); 371 372 cy = mpn_sub (n2p, n2p, rn, tp + in, qn); 373 MPN_COPY (rp + in, n2p, dn - in); 374 quotient_too_large |= cy; 375 cy = mpn_sub_n (rp, np, tp, in); 376 cy = mpn_sub_1 (rp + in, rp + in, rn, cy); 377 quotient_too_large |= cy; 378 foo: 379 if (quotient_too_large) 380 { 381 mpn_decr_u (qp, (mp_limb_t) 1); 382 mpn_add_n (rp, rp, dp, dn); 383 } 384 } 385 TMP_FREE; 386 return; 387 } 388 } 389 }