1 /* mpz_addmul_ui(prodsum, multiplier, small_multiplicand) --
2 Add MULTIPLICATOR times SMALL_MULTIPLICAND to PRODSUM.
4 Copyright (C) 1997, 2000 Free Software Foundation, Inc.
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
21 MA 02111-1307, USA. */
26 static mp_limb_t mpn_neg1 _PROTO ((mp_ptr, mp_size_t));
30 #define MPN_NORMALIZE(DST, NLIMBS) \
32 while (--(NLIMBS) >= 0 && (DST)[NLIMBS] == 0) \
36 #undef MPN_NORMALIZE_NOT_ZERO
37 #define MPN_NORMALIZE_NOT_ZERO(DST, NLIMBS) \
39 while ((DST)[--(NLIMBS)] == 0) \
47 mpz_addmul_ui (mpz_ptr rz, mpz_srcptr az, unsigned long int bu)
49 mpz_addmul_ui (rz, az, bu)
60 /* If either multiplier is zero, result is unaffected. */
61 if (bu == 0 || an == 0)
72 _mpz_realloc (rz, an + 1);
75 cy = mpn_mul_1 (rp, ap, an, (mp_limb_t) bu);
78 SIZ (rz) = SIZ (az) >= 0 ? an : -an;
84 /* Sign of operands are the same--really add. */
91 _mpz_realloc (rz, rn + 1);
94 cy = mpn_addmul_1 (rp, ap, an, (mp_limb_t) bu);
95 cy = mpn_add_1 (rp + an, rp + an, rn - an, cy);
98 SIZ (rz) = SIZ (rz) >= 0 ? rn : -rn;
104 if (ALLOC (rz) <= an)
105 _mpz_realloc (rz, an + 1);
108 cy = mpn_addmul_1 (rp, ap, rn, (mp_limb_t) bu);
112 cy2 = mpn_mul_1 (rp + rn, ap + rn, an - rn, (mp_limb_t) bu);
113 cy = cy2 + mpn_add_1 (rp + rn, rp + rn, an - rn, cy);
118 SIZ (rz) = SIZ (rz) >= 0 ? rn : -rn;
124 /* Sign of operands are different--actually subtract. */
132 cy = mpn_submul_1 (rp, ap, an, (mp_limb_t) bu);
133 cy = mpn_sub_1 (rp + an, rp + an, rn - an, cy);
137 MPN_NORMALIZE_NOT_ZERO (rp, rn);
141 MPN_NORMALIZE (rp, rn);
145 SIZ (rz) = SIZ (rz) >= 0 ? -rn : rn;
150 /* Tricky case. We need to subtract an operand that might be larger
151 than the minuend. To avoid allocating temporary space, we compute
152 a*b-r instead of r-a*b and then negate. */
154 if (ALLOC (rz) <= an)
155 _mpz_realloc (rz, an + 1);
158 cy = mpn_submul_1 (rp, ap, rn, (mp_limb_t) bu);
162 cy -= mpn_neg1 (rp, rn);
163 cy2 = mpn_mul_1 (rp + rn, ap + rn, an - rn, (mp_limb_t) bu);
164 if (cy == ~(mp_limb_t) 0)
165 cy = cy2 - mpn_sub_1 (rp + rn, rp + rn, an - rn, (mp_limb_t) 1);
167 cy = cy2 + mpn_add_1 (rp + rn, rp + rn, an - rn, cy);
170 rn -= rp[rn - 1] == 0;
174 cy -= mpn_neg1 (rp, rn);
177 MPN_NORMALIZE_NOT_ZERO (rp, rn);
182 MPN_NORMALIZE (rp, rn);
186 SIZ (rz) = SIZ (rz) >= 0 ? -rn : rn;
194 mpn_neg1 (mp_ptr rp, mp_size_t rn)
203 while (rn != 0 && rp[0] == 0)
209 for (i = 1; i < rn; i++)