1 /* mpz_add_ui, mpz_sub_ui -- Add or subtract an mpz_t and an unsigned
4 Copyright 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2002, 2004 Free Software
7 This file is part of the GNU MP Library.
9 The GNU MP Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
14 The GNU MP Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
26 #ifdef OPERATION_add_ui
27 #define FUNCTION mpz_add_ui
28 #define FUNCTION2 mpz_add
29 #define VARIATION_CMP >=
31 #define VARIATION_UNNEG -
34 #ifdef OPERATION_sub_ui
35 #define FUNCTION mpz_sub_ui
36 #define FUNCTION2 mpz_sub
37 #define VARIATION_CMP <
38 #define VARIATION_NEG -
39 #define VARIATION_UNNEG
43 Error
, need OPERATION_add_ui
or OPERATION_sub_ui
48 FUNCTION (mpz_ptr w
, mpz_srcptr u
, unsigned long int vval
)
52 mp_size_t usize
, wsize
;
55 #if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */
56 if (vval
> GMP_NUMB_MAX
)
61 vl
[0] = vval
& GMP_NUMB_MASK
;
62 vl
[1] = vval
>> GMP_NUMB_BITS
;
70 abs_usize
= ABS (usize
);
72 /* If not space for W (and possible carry), increase space. */
73 wsize
= abs_usize
+ 1;
74 if (w
->_mp_alloc
< wsize
)
75 _mpz_realloc (w
, wsize
);
77 /* These must be after realloc (U may be the same as W). */
84 w
->_mp_size
= VARIATION_NEG (vval
!= 0);
88 if (usize VARIATION_CMP
0)
91 cy
= mpn_add_1 (wp
, up
, abs_usize
, (mp_limb_t
) vval
);
93 wsize
= VARIATION_NEG (abs_usize
+ cy
);
97 /* The signs are different. Need exact comparison to determine
98 which operand to subtract from which. */
99 if (abs_usize
== 1 && up
[0] < vval
)
101 wp
[0] = vval
- up
[0];
102 wsize
= VARIATION_NEG
1;
106 mpn_sub_1 (wp
, up
, abs_usize
, (mp_limb_t
) vval
);
107 /* Size can decrease with at most one limb. */
108 wsize
= VARIATION_UNNEG (abs_usize
- (wp
[abs_usize
- 1] == 0));