1 1.1 mrg /* mpz_cdiv_q_ui -- Division rounding the quotient towards +infinity. The 2 1.1 mrg remainder gets the opposite sign as the denominator. In order to make it 3 1.1 mrg always fit into the return type, the negative of the true remainder is 4 1.1 mrg returned. 5 1.1 mrg 6 1.1.1.2 mrg Copyright 1994, 1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation, 7 1.1.1.2 mrg Inc. 8 1.1 mrg 9 1.1 mrg This file is part of the GNU MP Library. 10 1.1 mrg 11 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify 12 1.1.1.3 mrg it under the terms of either: 13 1.1.1.3 mrg 14 1.1.1.3 mrg * the GNU Lesser General Public License as published by the Free 15 1.1.1.3 mrg Software Foundation; either version 3 of the License, or (at your 16 1.1.1.3 mrg option) any later version. 17 1.1.1.3 mrg 18 1.1.1.3 mrg or 19 1.1.1.3 mrg 20 1.1.1.3 mrg * the GNU General Public License as published by the Free Software 21 1.1.1.3 mrg Foundation; either version 2 of the License, or (at your option) any 22 1.1.1.3 mrg later version. 23 1.1.1.3 mrg 24 1.1.1.3 mrg or both in parallel, as here. 25 1.1 mrg 26 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but 27 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 28 1.1.1.3 mrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 29 1.1.1.3 mrg for more details. 30 1.1 mrg 31 1.1.1.3 mrg You should have received copies of the GNU General Public License and the 32 1.1.1.3 mrg GNU Lesser General Public License along with the GNU MP Library. If not, 33 1.1.1.3 mrg see https://www.gnu.org/licenses/. */ 34 1.1 mrg 35 1.1 mrg #include "gmp-impl.h" 36 1.1 mrg 37 1.1 mrg unsigned long int 38 1.1 mrg mpz_cdiv_q_ui (mpz_ptr quot, mpz_srcptr dividend, unsigned long int divisor) 39 1.1 mrg { 40 1.1 mrg mp_size_t ns, nn, qn; 41 1.1 mrg mp_ptr np, qp; 42 1.1 mrg mp_limb_t rl; 43 1.1 mrg 44 1.1.1.2 mrg if (UNLIKELY (divisor == 0)) 45 1.1 mrg DIVIDE_BY_ZERO; 46 1.1 mrg 47 1.1 mrg ns = SIZ(dividend); 48 1.1 mrg if (ns == 0) 49 1.1 mrg { 50 1.1 mrg SIZ(quot) = 0; 51 1.1 mrg return 0; 52 1.1 mrg } 53 1.1 mrg 54 1.1 mrg nn = ABS(ns); 55 1.1.1.2 mrg qp = MPZ_REALLOC (quot, nn); 56 1.1 mrg np = PTR(dividend); 57 1.1 mrg 58 1.1 mrg #if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ 59 1.1 mrg if (divisor > GMP_NUMB_MAX) 60 1.1 mrg { 61 1.1 mrg mp_limb_t dp[2], rp[2]; 62 1.1 mrg 63 1.1 mrg if (nn == 1) /* tdiv_qr requirements; tested above for 0 */ 64 1.1 mrg { 65 1.1 mrg qp[0] = 0; 66 1.1 mrg rl = np[0]; 67 1.1 mrg qn = 1; /* a white lie, fixed below */ 68 1.1 mrg } 69 1.1 mrg else 70 1.1 mrg { 71 1.1 mrg dp[0] = divisor & GMP_NUMB_MASK; 72 1.1 mrg dp[1] = divisor >> GMP_NUMB_BITS; 73 1.1 mrg mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2); 74 1.1 mrg rl = rp[0] + (rp[1] << GMP_NUMB_BITS); 75 1.1 mrg qn = nn - 2 + 1; 76 1.1 mrg } 77 1.1 mrg 78 1.1 mrg if (rl != 0 && ns >= 0) 79 1.1 mrg { 80 1.1 mrg mpn_incr_u (qp, (mp_limb_t) 1); 81 1.1 mrg rl = divisor - rl; 82 1.1 mrg } 83 1.1 mrg 84 1.1 mrg qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0; 85 1.1 mrg } 86 1.1 mrg else 87 1.1 mrg #endif 88 1.1 mrg { 89 1.1 mrg rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor); 90 1.1 mrg 91 1.1 mrg if (rl != 0 && ns >= 0) 92 1.1 mrg { 93 1.1 mrg mpn_incr_u (qp, (mp_limb_t) 1); 94 1.1 mrg rl = divisor - rl; 95 1.1 mrg } 96 1.1 mrg 97 1.1 mrg qn = nn - (qp[nn - 1] == 0); 98 1.1 mrg } 99 1.1 mrg 100 1.1 mrg SIZ(quot) = ns >= 0 ? qn : -qn; 101 1.1 mrg return rl; 102 1.1 mrg } 103