1/* mpz_ui_sub -- Subtract an unsigned one-word integer and an mpz_t. 2 3Copyright 2002, 2004 Free Software Foundation, Inc. 4 5This file is part of the GNU MP Library. 6 7The GNU MP Library is free software; you can redistribute it and/or modify 8it under the terms of the GNU Lesser General Public License as published by 9the Free Software Foundation; either version 3 of the License, or (at your 10option) any later version. 11 12The GNU MP Library is distributed in the hope that it will be useful, but 13WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 15License for more details. 16 17You should have received a copy of the GNU Lesser General Public License 18along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 19 20#include "gmp.h" 21#include "gmp-impl.h" 22 23void 24mpz_ui_sub (mpz_ptr w, unsigned long int uval, mpz_srcptr v) 25{ 26 mp_ptr vp, wp; 27 mp_size_t vn, wn; 28 mp_limb_t cy; 29 30#if BITS_PER_ULONG > GMP_NUMB_BITS /* avoid warnings about shift amount */ 31 if (uval > GMP_NUMB_MAX) 32 { 33 mpz_t u; 34 mp_limb_t ul[2]; 35 PTR(u) = ul; 36 ul[0] = uval & GMP_NUMB_MASK; 37 ul[1] = uval >> GMP_NUMB_BITS; 38 SIZ(u) = 2; 39 mpz_sub (w, u, v); 40 return; 41 } 42#endif 43 44 vp = PTR(v); 45 vn = SIZ(v); 46 47 wp = PTR(w); 48 49 if (vn > 1) 50 { 51 wp = MPZ_REALLOC (w, vn); 52 vp = PTR(v); 53 mpn_sub_1 (wp, vp, vn, (mp_limb_t) uval); 54 wn = -(vn - (wp[vn - 1] == 0)); 55 } 56 else if (vn == 1) 57 { 58 if (uval >= vp[0]) 59 { 60 wp[0] = uval - vp[0]; 61 wn = wp[0] != 0; 62 } 63 else 64 { 65 wp[0] = vp[0] - uval; 66 wn = -1; 67 } 68 } 69 else if (vn == 0) 70 { 71 wp[0] = uval; 72 wn = uval != 0; 73 } 74 else /* (vn < 0) */ 75 { 76 vn = -vn; 77 wp = MPZ_REALLOC (w, vn + 1); 78 vp = PTR(v); 79 cy = mpn_add_1 (wp, vp, vn, (mp_limb_t) uval); 80 wp[vn] = cy; 81 wn = vn + (cy != 0); 82 } 83 84 SIZ(w) = wn; 85} 86