Home | History | Annotate | Line # | Download | only in generic
      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