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++)