[BACK]Return to mul_ui.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gmp / mpfr

Annotation of OpenXM_contrib/gmp/mpfr/mul_ui.c, Revision 1.1.1.1

1.1       maekawa     1: /* mpfr_mul_ui -- multiply a floating-point number by a machine integer
                      2:
                      3: Copyright (C) 1999 PolKA project, Inria Lorraine and Loria
                      4:
                      5: This file is part of the MPFR Library.
                      6:
                      7: The MPFR Library is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU Library General Public License as published by
                      9: the Free Software Foundation; either version 2 of the License, or (at your
                     10: option) any later version.
                     11:
                     12: The MPFR Library is distributed in the hope that it will be useful, but
                     13: WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
                     15: License for more details.
                     16:
                     17: You should have received a copy of the GNU Library General Public License
                     18: along with the MPFR Library; see the file COPYING.LIB.  If not, write to
                     19: the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
                     20: MA 02111-1307, USA. */
                     21:
                     22: #include <stdio.h>
                     23: #include "gmp.h"
                     24: #include "gmp-impl.h"
                     25: #include "longlong.h"
                     26: #include "mpfr.h"
                     27:
                     28: void
                     29: #if __STDC__
                     30: mpfr_mul_ui(mpfr_ptr y, mpfr_srcptr x, unsigned long u, unsigned char RND_MODE)
                     31: #else
                     32: mpfr_mul_ui(y, x, u, RND_MODE)
                     33:      mpfr_ptr y;
                     34:      mpfr_srcptr x;
                     35:      unsigned long u;
                     36:      unsigned char RND_MODE;
                     37: #endif
                     38: {
                     39:   mp_limb_t carry, *my, *old_my; unsigned long c;
                     40:   unsigned long xsize, ysize, cnt, dif;
                     41:   TMP_DECL(marker);
                     42:
                     43:   TMP_MARK(marker);
                     44:   my = MANT(y);
                     45:   ysize = (PREC(y)-1)/BITS_PER_MP_LIMB + 1;
                     46:   xsize = (PREC(x)-1)/BITS_PER_MP_LIMB + 1;
                     47:
                     48:   if (ysize < xsize) {
                     49:       old_my = my;
                     50:       my = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB);
                     51:       dif=0;
                     52:     }
                     53:   else dif=ysize-xsize;
                     54:
                     55:   carry = mpn_mul_1(my+dif, MANT(x), xsize, u);
                     56:   MPN_ZERO(my, dif);
                     57:
                     58:   /* WARNING: count_leading_zeros is undefined for carry=0 */
                     59:   if (carry) count_leading_zeros(cnt, carry);
                     60:   else cnt=BITS_PER_MP_LIMB;
                     61:
                     62:   c = mpfr_round_raw(my, my, PREC(x), (SIGN(x)<0),
                     63:                     PREC(y)-BITS_PER_MP_LIMB+cnt, RND_MODE);
                     64:
                     65:   /* If cnt = 1111111111111 and c = 1 we shall get depressed */
                     66:   if (c && (carry == (((mp_limb_t)1) << (BITS_PER_MP_LIMB - cnt)) - 1))
                     67:     {
                     68:       cnt--;
                     69:       mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt);
                     70:       my[ysize - 1] |= ((mp_limb_t) 1) << (BITS_PER_MP_LIMB - 1);
                     71:     }
                     72:   else
                     73:     {
                     74:       /* Warning: mpn_rshift is undefined for shift=0 */
                     75:       if (cnt!=BITS_PER_MP_LIMB)
                     76:        mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt);
                     77:       my[ysize - 1] |= (carry << cnt);
                     78:     }
                     79:   EXP(y) = EXP(x) + BITS_PER_MP_LIMB - cnt;
                     80:   if (ysize < xsize) MPN_COPY(old_my, my, ysize);
                     81:   /* set sign */
                     82:   if (SIGN(y) != SIGN(x)) CHANGE_SIGN(y);
                     83:   TMP_FREE(marker);
                     84: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>