| OLD | NEW |
| (Empty) |
| 1 /* mpn_sb_bdiv_qr -- schoolbook Hensel division with precomputed inverse, | |
| 2 returning quotient and remainder. | |
| 3 | |
| 4 Contributed to the GNU project by Niels Möller. | |
| 5 | |
| 6 THE FUNCTIONS IN THIS FILE ARE INTERNAL FUNCTIONS WITH MUTABLE INTERFACES. | |
| 7 IT IS ONLY SAFE TO REACH THEM THROUGH DOCUMENTED INTERFACES. | |
| 8 | |
| 9 Copyright 2006 Free Software Foundation, Inc. | |
| 10 | |
| 11 This file is part of the GNU MP Library. | |
| 12 | |
| 13 The GNU MP Library is free software; you can redistribute it and/or modify | |
| 14 it under the terms of the GNU Lesser General Public License as published by | |
| 15 the Free Software Foundation; either version 3 of the License, or (at your | |
| 16 option) any later version. | |
| 17 | |
| 18 The GNU MP Library is distributed in the hope that it will be useful, but | |
| 19 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 20 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 21 License for more details. | |
| 22 | |
| 23 You should have received a copy of the GNU Lesser General Public License | |
| 24 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ | |
| 25 | |
| 26 #include "gmp.h" | |
| 27 #include "gmp-impl.h" | |
| 28 | |
| 29 | |
| 30 /* Computes a binary quotient of size qn = nn - dn. | |
| 31 Output: | |
| 32 | |
| 33 Q = N * D^{-1} mod B^qn, | |
| 34 | |
| 35 R = (N - Q * D) * B^(-qn) | |
| 36 | |
| 37 Stores the dn least significant limbs of R at {np + nn - dn, dn}, | |
| 38 and returns the borrow from the subtraction N - Q*D. | |
| 39 | |
| 40 D must be odd. dinv is (-D)^-1 mod B. */ | |
| 41 | |
| 42 mp_limb_t | |
| 43 mpn_sb_bdiv_qr (mp_ptr qp, | |
| 44 mp_ptr np, mp_size_t nn, | |
| 45 mp_srcptr dp, mp_size_t dn, mp_limb_t dinv) | |
| 46 { | |
| 47 mp_size_t qn; | |
| 48 mp_size_t i; | |
| 49 mp_limb_t rh; | |
| 50 mp_limb_t ql; | |
| 51 | |
| 52 ASSERT (nn > 0); | |
| 53 ASSERT (dn > 0); | |
| 54 ASSERT (nn > dn); | |
| 55 ASSERT (dp[0] & 1); | |
| 56 | |
| 57 qn = nn - dn; | |
| 58 | |
| 59 rh = 0; | |
| 60 | |
| 61 /* To complete the negation, this value is added to q. */ | |
| 62 ql = 1; | |
| 63 while (qn > dn) | |
| 64 { | |
| 65 for (i = 0; i < dn; i++) | |
| 66 { | |
| 67 mp_limb_t q; | |
| 68 | |
| 69 q = dinv * np[i]; | |
| 70 qp[i] = ~q; | |
| 71 | |
| 72 np[i] = mpn_addmul_1 (np + i, dp, dn, q); | |
| 73 } | |
| 74 rh += mpn_add (np + dn, np + dn, qn, np, dn); | |
| 75 ql = mpn_add_1 (qp, qp, dn, ql); | |
| 76 | |
| 77 qp += dn; qn -= dn; | |
| 78 np += dn; nn -= dn; | |
| 79 } | |
| 80 | |
| 81 for (i = 0; i < qn; i++) | |
| 82 { | |
| 83 mp_limb_t q; | |
| 84 | |
| 85 q = dinv * np[i]; | |
| 86 qp[i] = ~q; | |
| 87 | |
| 88 np[i] = mpn_addmul_1 (np + i, dp, dn, q); | |
| 89 } | |
| 90 | |
| 91 rh += mpn_add_n (np + dn, np + dn, np, qn); | |
| 92 ql = mpn_add_1 (qp, qp, qn, ql); | |
| 93 | |
| 94 if (UNLIKELY (ql > 0)) | |
| 95 { | |
| 96 /* q == 0 */ | |
| 97 ASSERT (rh == 0); | |
| 98 return 0; | |
| 99 } | |
| 100 else | |
| 101 { | |
| 102 mp_limb_t cy; | |
| 103 | |
| 104 cy = mpn_sub_n (np + qn, np + qn, dp, dn); | |
| 105 ASSERT (cy >= rh); | |
| 106 return cy - rh; | |
| 107 } | |
| 108 } | |
| OLD | NEW |