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