/* mpf_add_ui -- Add a float and an unsigned integer. Copyright (C) 1993, 1994, 1996 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 the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU MP Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "gmp.h" #include "gmp-impl.h" void #if __STDC__ mpf_add_ui (mpf_ptr sum, mpf_srcptr u, unsigned long int v) #else mpf_add_ui (sum, u, v) mpf_ptr sum; mpf_srcptr u; unsigned long int v; #endif { mp_srcptr up = u->_mp_d; mp_ptr sump = sum->_mp_d; mp_size_t usize, sumsize; mp_size_t prec = sum->_mp_prec; mp_exp_t uexp = u->_mp_exp; usize = u->_mp_size; if (usize <= 0) { if (usize == 0) { mpf_set_ui (sum, v); return; } else { __mpf_struct u_negated; u_negated._mp_size = -usize; u_negated._mp_exp = u->_mp_exp; u_negated._mp_d = u->_mp_d; mpf_sub_ui (sum, &u_negated, v); sum->_mp_size = -(sum->_mp_size); return; } } if (v == 0) { sum_is_u: if (u != sum) { sumsize = MIN (usize, prec + 1); MPN_COPY (sum->_mp_d, up + usize - sumsize, sumsize); sum->_mp_size = sumsize; sum->_mp_exp = u->_mp_exp; } return; } if (uexp > 0) { /* U >= 1. */ if (uexp > prec) { /* U >> V, V is not part of final result. */ goto sum_is_u; } else { /* U's "limb point" is somewhere between the first limb and the PREC:th limb. Both U and V are part of the final result. */ if (uexp > usize) { /* uuuuuu0000. */ /* + v. */ /* We begin with moving U to the top of SUM, to handle samevar(U,SUM). */ MPN_COPY_DECR (sump + uexp - usize, up, usize); sump[0] = v; MPN_ZERO (sump + 1, uexp - usize - 1); #if 0 /* What is this??? */ if (sum == u) MPN_COPY (sum->_mp_d, sump, uexp); #endif sum->_mp_size = uexp; sum->_mp_exp = uexp; } else { /* uuuuuu.uuuu */ /* + v. */ mp_limb_t cy_limb; if (usize > prec) { /* Ignore excess limbs in U. */ up += usize - prec; usize -= usize - prec; /* Eq. usize = prec */ } if (sump != up) MPN_COPY (sump, up, usize - uexp); cy_limb = mpn_add_1 (sump + usize - uexp, up + usize - uexp, uexp, (mp_limb_t) v); sump[usize] = cy_limb; sum->_mp_size = usize + cy_limb; sum->_mp_exp = uexp + cy_limb; } } } else { /* U < 1, so V > U for sure. */ /* v. */ /* .0000uuuu */ if ((-uexp) >= prec) { sump[0] = v; sum->_mp_size = 1; sum->_mp_exp = 1; } else { if (usize + (-uexp) + 1 > prec) { /* Ignore excess limbs in U. */ up += usize + (-uexp) + 1 - prec; usize -= usize + (-uexp) + 1 - prec; } if (sump != up) MPN_COPY (sump, up, usize); MPN_ZERO (sump + usize, -uexp); sump[usize + (-uexp)] = v; sum->_mp_size = usize + (-uexp) + 1; sum->_mp_exp = 1; } } }