fdiv_qr_ui.c revision 1.1.1.3 1 1.1 mrg /* mpz_fdiv_qr_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.3 mrg Copyright 1994-1996, 1999, 2001, 2002, 2004, 2012 Free Software Foundation,
5 1.1 mrg 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.h"
34 1.1 mrg #include "gmp-impl.h"
35 1.1 mrg
36 1.1 mrg unsigned long int
37 1.1 mrg mpz_fdiv_qr_ui (mpz_ptr quot, mpz_ptr rem, mpz_srcptr dividend, unsigned long int divisor)
38 1.1 mrg {
39 1.1 mrg mp_size_t ns, nn, qn;
40 1.1 mrg mp_ptr np, qp;
41 1.1 mrg mp_limb_t rl;
42 1.1 mrg
43 1.1.1.2 mrg if (UNLIKELY (divisor == 0))
44 1.1 mrg DIVIDE_BY_ZERO;
45 1.1 mrg
46 1.1 mrg ns = SIZ(dividend);
47 1.1 mrg if (ns == 0)
48 1.1 mrg {
49 1.1 mrg SIZ(quot) = 0;
50 1.1 mrg SIZ(rem) = 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];
62 1.1 mrg mp_ptr rp;
63 1.1 mrg mp_size_t rn;
64 1.1 mrg
65 1.1 mrg MPZ_REALLOC (rem, 2);
66 1.1 mrg rp = PTR(rem);
67 1.1 mrg
68 1.1 mrg if (nn == 1) /* tdiv_qr requirements; tested above for 0 */
69 1.1 mrg {
70 1.1 mrg qp[0] = 0;
71 1.1 mrg qn = 1; /* a white lie, fixed below */
72 1.1 mrg rl = np[0];
73 1.1 mrg rp[0] = rl;
74 1.1 mrg }
75 1.1 mrg else
76 1.1 mrg {
77 1.1 mrg dp[0] = divisor & GMP_NUMB_MASK;
78 1.1 mrg dp[1] = divisor >> GMP_NUMB_BITS;
79 1.1 mrg mpn_tdiv_qr (qp, rp, (mp_size_t) 0, np, nn, dp, (mp_size_t) 2);
80 1.1 mrg rl = rp[0] + (rp[1] << GMP_NUMB_BITS);
81 1.1 mrg qn = nn - 2 + 1;
82 1.1 mrg }
83 1.1 mrg
84 1.1 mrg if (rl != 0 && ns < 0)
85 1.1 mrg {
86 1.1 mrg mpn_incr_u (qp, (mp_limb_t) 1);
87 1.1 mrg rl = divisor - rl;
88 1.1 mrg rp[0] = rl & GMP_NUMB_MASK;
89 1.1 mrg rp[1] = rl >> GMP_NUMB_BITS;
90 1.1 mrg }
91 1.1 mrg
92 1.1 mrg qn -= qp[qn - 1] == 0; qn -= qn != 0 && qp[qn - 1] == 0;
93 1.1 mrg rn = 1 + (rl > GMP_NUMB_MAX); rn -= (rp[rn - 1] == 0);
94 1.1 mrg SIZ(rem) = rn;
95 1.1 mrg }
96 1.1 mrg else
97 1.1 mrg #endif
98 1.1 mrg {
99 1.1 mrg rl = mpn_divrem_1 (qp, (mp_size_t) 0, np, nn, (mp_limb_t) divisor);
100 1.1 mrg if (rl == 0)
101 1.1 mrg SIZ(rem) = 0;
102 1.1 mrg else
103 1.1 mrg {
104 1.1 mrg if (ns < 0)
105 1.1 mrg {
106 1.1 mrg mpn_incr_u (qp, (mp_limb_t) 1);
107 1.1 mrg rl = divisor - rl;
108 1.1 mrg }
109 1.1 mrg
110 1.1 mrg PTR(rem)[0] = rl;
111 1.1 mrg SIZ(rem) = rl != 0;
112 1.1 mrg }
113 1.1 mrg qn = nn - (qp[nn - 1] == 0);
114 1.1 mrg }
115 1.1 mrg
116 1.1 mrg SIZ(quot) = ns >= 0 ? qn : -qn;
117 1.1 mrg return rl;
118 1.1 mrg }
119