From 11da511c784eca003deb90c23570f0873954e0de Mon Sep 17 00:00:00 2001 From: Duncan Wilkie Date: Sat, 18 Nov 2023 06:11:09 -0600 Subject: Initial commit. --- gmp-6.3.0/mpz/aors.h | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 gmp-6.3.0/mpz/aors.h (limited to 'gmp-6.3.0/mpz/aors.h') diff --git a/gmp-6.3.0/mpz/aors.h b/gmp-6.3.0/mpz/aors.h new file mode 100644 index 0000000..782a5fe --- /dev/null +++ b/gmp-6.3.0/mpz/aors.h @@ -0,0 +1,129 @@ +/* mpz_add, mpz_sub -- add or subtract integers. + +Copyright 1991, 1993, 1994, 1996, 2000, 2001, 2011, 2012, 2020 Free +Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of either: + + * the GNU Lesser General Public License as published by the Free + Software Foundation; either version 3 of the License, or (at your + option) any later version. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +The GNU MP Library is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" + + +#ifdef OPERATION_add +#define FUNCTION mpz_add +#define VARIATION +#endif +#ifdef OPERATION_sub +#define FUNCTION mpz_sub +#define VARIATION - +#endif + +#ifndef FUNCTION +Error, need OPERATION_add or OPERATION_sub +#endif + + +void +FUNCTION (mpz_ptr w, mpz_srcptr u, mpz_srcptr v) +{ + mp_srcptr up, vp; + mp_ptr wp; + mp_size_t usize, vsize, wsize; + mp_size_t abs_usize; + mp_size_t abs_vsize; + + usize = SIZ(u); + vsize = VARIATION SIZ(v); + abs_usize = ABS (usize); + abs_vsize = ABS (vsize); + + if (abs_usize < abs_vsize) + { + /* Swap U and V. */ + MPZ_SRCPTR_SWAP (u, v); + MP_SIZE_T_SWAP (usize, vsize); + MP_SIZE_T_SWAP (abs_usize, abs_vsize); + } + + /* True: ABS_USIZE >= ABS_VSIZE. */ + + /* If not space for w (and possible carry), increase space. */ + wsize = abs_usize + 1; + wp = MPZ_REALLOC (w, wsize); + + /* These must be after realloc (u or v may be the same as w). */ + up = PTR(u); + vp = PTR(v); + + if ((usize ^ vsize) < 0) + { + /* U and V have different sign. Need to compare them to determine + which operand to subtract from which. */ + + /* This test is right since ABS_USIZE >= ABS_VSIZE. */ + if (abs_usize != abs_vsize) + { + mpn_sub (wp, up, abs_usize, vp, abs_vsize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize < 0) + wsize = -wsize; + } + else + { + int cmp = mpn_cmp (up, vp, abs_usize); + if (cmp < 0) + { + mpn_sub_n (wp, vp, up, abs_usize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize >= 0) + wsize = -wsize; + } + else if (cmp > 0) + { + mpn_sub_n (wp, up, vp, abs_usize); + wsize = abs_usize; + MPN_NORMALIZE_NOT_ZERO (wp, wsize); + if (usize < 0) + wsize = -wsize; + } + else + wsize = 0; + } + } + else + { + /* U and V have same sign. Add them. */ + mp_limb_t cy_limb = mpn_add (wp, up, abs_usize, vp, abs_vsize); + wp[abs_usize] = cy_limb; + wsize = abs_usize + cy_limb; + if (usize < 0) + wsize = -wsize; + } + + SIZ(w) = wsize; +} -- cgit v1.2.3