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