source: trunk/third/gmp/mpz/aors_ui.h @ 18191

Revision 18191, 2.8 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18190, which included commits to RCS files with non-trunk default branches.
Line 
1/* mpz_add_ui, mpz_sub_ui -- Add or subtract an mpz_t and an unsigned
2   one-word integer.
3
4Copyright 1991, 1993, 1994, 1996, 1999, 2000, 2001, 2002 Free Software
5Foundation, Inc.
6
7This file is part of the GNU MP Library.
8
9The GNU MP Library is free software; you can redistribute it and/or modify
10it under the terms of the GNU Lesser General Public License as published by
11the Free Software Foundation; either version 2.1 of the License, or (at your
12option) any later version.
13
14The GNU MP Library is distributed in the hope that it will be useful, but
15WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
17License for more details.
18
19You should have received a copy of the GNU Lesser General Public License
20along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
21the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22MA 02111-1307, USA. */
23
24#include "gmp.h"
25#include "gmp-impl.h"
26
27
28#ifdef OPERATION_add_ui
29#define FUNCTION          mpz_add_ui
30#define FUNCTION2         mpz_add
31#define VARIATION_CMP     >=
32#define VARIATION_NEG
33#define VARIATION_UNNEG   -
34#endif
35
36#ifdef OPERATION_sub_ui
37#define FUNCTION          mpz_sub_ui
38#define FUNCTION2         mpz_sub
39#define VARIATION_CMP     <
40#define VARIATION_NEG     -
41#define VARIATION_UNNEG
42#endif
43
44#ifndef FUNCTION
45Error, need OPERATION_add_ui or OPERATION_sub_ui
46#endif
47
48
49void
50FUNCTION (mpz_ptr w, mpz_srcptr u, unsigned long int vval)
51{
52  mp_srcptr up;
53  mp_ptr wp;
54  mp_size_t usize, wsize;
55  mp_size_t abs_usize;
56
57#if GMP_NAIL_BITS != 0
58  if (vval > GMP_NUMB_MAX)
59    {
60      mpz_t v;
61      mp_limb_t vl[2];
62      PTR(v) = vl;
63      vl[0] = vval & GMP_NUMB_MASK;
64      vl[1] = vval >> GMP_NUMB_BITS;
65      SIZ(v) = 2;
66      FUNCTION2 (w, u, v);
67      return;
68    }
69#endif
70
71  usize = u->_mp_size;
72  abs_usize = ABS (usize);
73
74  /* If not space for W (and possible carry), increase space.  */
75  wsize = abs_usize + 1;
76  if (w->_mp_alloc < wsize)
77    _mpz_realloc (w, wsize);
78
79  /* These must be after realloc (U may be the same as W).  */
80  up = u->_mp_d;
81  wp = w->_mp_d;
82
83  if (abs_usize == 0)
84    {
85      wp[0] = vval;
86      w->_mp_size = VARIATION_NEG (vval != 0);
87      return;
88    }
89
90  if (usize VARIATION_CMP 0)
91    {
92      mp_limb_t cy;
93      cy = mpn_add_1 (wp, up, abs_usize, (mp_limb_t) vval);
94      wp[abs_usize] = cy;
95      wsize = VARIATION_NEG (abs_usize + cy);
96    }
97  else
98    {
99      /* The signs are different.  Need exact comparison to determine
100         which operand to subtract from which.  */
101      if (abs_usize == 1 && up[0] < vval)
102        {
103          wp[0] = vval - up[0];
104          wsize = VARIATION_NEG 1;
105        }
106      else
107        {
108          mpn_sub_1 (wp, up, abs_usize, (mp_limb_t) vval);
109          /* Size can decrease with at most one limb.  */
110          wsize = VARIATION_UNNEG (abs_usize - (wp[abs_usize - 1] == 0));
111        }
112    }
113
114  w->_mp_size = wsize;
115}
Note: See TracBrowser for help on using the repository browser.