1 1.1 mrg /* mpn_dcpi1_bdiv_q -- divide-and-conquer Hensel division with precomputed 2 1.1 mrg inverse, returning quotient. 3 1.1 mrg 4 1.1.1.3 mrg Contributed to the GNU project by Niels Mller and Torbjorn Granlund. 5 1.1 mrg 6 1.1 mrg THE FUNCTIONS IN THIS FILE ARE INTERNAL WITH MUTABLE INTERFACES. IT IS ONLY 7 1.1 mrg SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. IN FACT, IT IS ALMOST 8 1.1 mrg GUARANTEED THAT THEY WILL CHANGE OR DISAPPEAR IN A FUTURE GMP RELEASE. 9 1.1 mrg 10 1.1.1.4 mrg Copyright 2006, 2007, 2009-2011, 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.1.5 mrg #if 0 /* unused, so leave out for now */ 41 1.1.1.4 mrg static mp_size_t 42 1.1 mrg mpn_dcpi1_bdiv_q_n_itch (mp_size_t n) 43 1.1 mrg { 44 1.1.1.4 mrg /* NOTE: Depends on mullo_n and mpn_dcpi1_bdiv_qr_n interface */ 45 1.1 mrg return n; 46 1.1 mrg } 47 1.1.1.5 mrg #endif 48 1.1 mrg 49 1.1.1.4 mrg /* Computes Q = - N / D mod B^n, destroys N. 50 1.1 mrg 51 1.1 mrg N = {np,n} 52 1.1 mrg D = {dp,n} 53 1.1 mrg */ 54 1.1 mrg 55 1.1.1.4 mrg static void 56 1.1 mrg mpn_dcpi1_bdiv_q_n (mp_ptr qp, 57 1.1 mrg mp_ptr np, mp_srcptr dp, mp_size_t n, 58 1.1 mrg mp_limb_t dinv, mp_ptr tp) 59 1.1 mrg { 60 1.1 mrg while (ABOVE_THRESHOLD (n, DC_BDIV_Q_THRESHOLD)) 61 1.1 mrg { 62 1.1 mrg mp_size_t lo, hi; 63 1.1 mrg mp_limb_t cy; 64 1.1 mrg 65 1.1 mrg lo = n >> 1; /* floor(n/2) */ 66 1.1 mrg hi = n - lo; /* ceil(n/2) */ 67 1.1 mrg 68 1.1 mrg cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, lo, dinv, tp); 69 1.1 mrg 70 1.1 mrg mpn_mullo_n (tp, qp, dp + hi, lo); 71 1.1.1.4 mrg mpn_add_n (np + hi, np + hi, tp, lo); 72 1.1 mrg 73 1.1 mrg if (lo < hi) 74 1.1 mrg { 75 1.1.1.4 mrg cy += mpn_addmul_1 (np + lo, qp, lo, dp[lo]); 76 1.1.1.4 mrg np[n - 1] += cy; 77 1.1 mrg } 78 1.1 mrg qp += lo; 79 1.1 mrg np += lo; 80 1.1 mrg n -= lo; 81 1.1 mrg } 82 1.1 mrg mpn_sbpi1_bdiv_q (qp, np, n, dp, n, dinv); 83 1.1 mrg } 84 1.1 mrg 85 1.1.1.4 mrg /* Computes Q = - N / D mod B^nn, destroys N. 86 1.1 mrg 87 1.1 mrg N = {np,nn} 88 1.1 mrg D = {dp,dn} 89 1.1 mrg */ 90 1.1 mrg 91 1.1 mrg void 92 1.1 mrg mpn_dcpi1_bdiv_q (mp_ptr qp, 93 1.1 mrg mp_ptr np, mp_size_t nn, 94 1.1 mrg mp_srcptr dp, mp_size_t dn, 95 1.1 mrg mp_limb_t dinv) 96 1.1 mrg { 97 1.1 mrg mp_size_t qn; 98 1.1 mrg mp_limb_t cy; 99 1.1 mrg mp_ptr tp; 100 1.1 mrg TMP_DECL; 101 1.1 mrg 102 1.1 mrg TMP_MARK; 103 1.1 mrg 104 1.1 mrg ASSERT (dn >= 2); 105 1.1 mrg ASSERT (nn - dn >= 0); 106 1.1 mrg ASSERT (dp[0] & 1); 107 1.1 mrg 108 1.1 mrg tp = TMP_SALLOC_LIMBS (dn); 109 1.1 mrg 110 1.1 mrg qn = nn; 111 1.1 mrg 112 1.1 mrg if (qn > dn) 113 1.1 mrg { 114 1.1 mrg /* Reduce qn mod dn in a super-efficient manner. */ 115 1.1 mrg do 116 1.1 mrg qn -= dn; 117 1.1 mrg while (qn > dn); 118 1.1 mrg 119 1.1 mrg /* Perform the typically smaller block first. */ 120 1.1 mrg if (BELOW_THRESHOLD (qn, DC_BDIV_QR_THRESHOLD)) 121 1.1 mrg cy = mpn_sbpi1_bdiv_qr (qp, np, 2 * qn, dp, qn, dinv); 122 1.1 mrg else 123 1.1 mrg cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, qn, dinv, tp); 124 1.1 mrg 125 1.1 mrg if (qn != dn) 126 1.1 mrg { 127 1.1 mrg if (qn > dn - qn) 128 1.1 mrg mpn_mul (tp, qp, qn, dp + qn, dn - qn); 129 1.1 mrg else 130 1.1 mrg mpn_mul (tp, dp + qn, dn - qn, qp, qn); 131 1.1 mrg mpn_incr_u (tp + qn, cy); 132 1.1 mrg 133 1.1.1.4 mrg mpn_add (np + qn, np + qn, nn - qn, tp, dn); 134 1.1 mrg cy = 0; 135 1.1 mrg } 136 1.1 mrg 137 1.1 mrg np += qn; 138 1.1 mrg qp += qn; 139 1.1 mrg 140 1.1 mrg qn = nn - qn; 141 1.1 mrg while (qn > dn) 142 1.1 mrg { 143 1.1.1.4 mrg mpn_add_1 (np + dn, np + dn, qn - dn, cy); 144 1.1 mrg cy = mpn_dcpi1_bdiv_qr_n (qp, np, dp, dn, dinv, tp); 145 1.1 mrg qp += dn; 146 1.1 mrg np += dn; 147 1.1 mrg qn -= dn; 148 1.1 mrg } 149 1.1 mrg mpn_dcpi1_bdiv_q_n (qp, np, dp, dn, dinv, tp); 150 1.1 mrg } 151 1.1 mrg else 152 1.1 mrg { 153 1.1 mrg if (BELOW_THRESHOLD (qn, DC_BDIV_Q_THRESHOLD)) 154 1.1 mrg mpn_sbpi1_bdiv_q (qp, np, qn, dp, qn, dinv); 155 1.1 mrg else 156 1.1 mrg mpn_dcpi1_bdiv_q_n (qp, np, dp, qn, dinv, tp); 157 1.1 mrg } 158 1.1 mrg 159 1.1 mrg TMP_FREE; 160 1.1 mrg } 161