[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.2

1.1       maekawa     1: /* mpfr_mul_ui -- multiply a floating-point number by a machine integer
                      2:
1.1.1.2 ! ohara       3: Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
1.1       maekawa     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
1.1.1.2 ! ohara       8: it under the terms of the GNU Lesser General Public License as published by
        !             9: the Free Software Foundation; either version 2.1 of the License, or (at your
1.1       maekawa    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
1.1.1.2 ! ohara      14: or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
1.1       maekawa    15: License for more details.
                     16:
1.1.1.2 ! ohara      17: You should have received a copy of the GNU Lesser General Public License
1.1       maekawa    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 "gmp.h"
                     23: #include "gmp-impl.h"
                     24: #include "longlong.h"
                     25: #include "mpfr.h"
1.1.1.2 ! ohara      26: #include "mpfr-impl.h"
1.1       maekawa    27:
1.1.1.2 ! ohara      28: int
        !            29: mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode)
1.1       maekawa    30: {
1.1.1.2 ! ohara      31:   mp_limb_t *yp, *old_yp;
        !            32:   mp_size_t xn, yn;
        !            33:   int cnt, c, inexact;
1.1       maekawa    34:   TMP_DECL(marker);
                     35:
1.1.1.2 ! ohara      36:   if (MPFR_IS_NAN(x))
        !            37:     {
        !            38:       MPFR_SET_NAN(y);
        !            39:       MPFR_RET_NAN;
        !            40:     }
        !            41:
        !            42:   if (MPFR_IS_INF(x))
        !            43:     {
        !            44:       if (u != 0)
        !            45:        {
        !            46:           MPFR_CLEAR_FLAGS(y);
        !            47:           MPFR_SET_INF(y);
        !            48:           MPFR_SET_SAME_SIGN(y, x);
        !            49:           MPFR_RET(0); /* infinity is exact */
        !            50:        }
        !            51:       else /* 0 * infinity */
        !            52:        {
        !            53:          MPFR_SET_NAN(y);
        !            54:           MPFR_RET_NAN;
        !            55:        }
        !            56:     }
        !            57:
        !            58:   MPFR_CLEAR_FLAGS(y);
        !            59:
        !            60:   if (u == 0 || MPFR_IS_ZERO(x))
        !            61:     {
        !            62:       MPFR_SET_ZERO(y);
        !            63:       MPFR_SET_SAME_SIGN(y, x);
        !            64:       MPFR_RET(0); /* zero is exact */
        !            65:     }
        !            66:
        !            67:   if (u == 1)
        !            68:     return mpfr_set (y, x, rnd_mode);
        !            69:
1.1       maekawa    70:   TMP_MARK(marker);
1.1.1.2 ! ohara      71:   yp = MPFR_MANT(y);
        !            72:   yn = (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB + 1;
        !            73:   xn = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB + 1;
        !            74:
        !            75:   old_yp = yp;
        !            76:
        !            77:   MPFR_ASSERTN(xn < MP_SIZE_T_MAX);
        !            78:   if (yn < xn + 1)
        !            79:     yp = (mp_ptr) TMP_ALLOC ((size_t) (xn + 1) * BYTES_PER_MP_LIMB);
        !            80:
        !            81:   yp[xn] = mpn_mul_1 (yp, MPFR_MANT(x), xn, u);
        !            82:
        !            83:   /* x * u is stored in yp[xn], ..., yp[0] */
        !            84:
        !            85:   /* since the case u=1 was treated above, we have u >= 2, thus
        !            86:      yp[xn] >= 1 since x was msb-normalized */
        !            87:   MPFR_ASSERTN(yp[xn] != 0);
        !            88:   if ((yp[xn] & GMP_LIMB_HIGHBIT) == 0)
        !            89:     {
        !            90:       count_leading_zeros(cnt, yp[xn]);
        !            91:       mpn_lshift (yp, yp, xn + 1, cnt);
1.1       maekawa    92:     }
                     93:   else
                     94:     {
1.1.1.2 ! ohara      95:       cnt = 0;
        !            96:     }
        !            97:
        !            98:   /* now yp[xn], ..., yp[0] is msb-normalized too, and has at most
        !            99:      PREC(x) + (BITS_PER_MP_LIMB - cnt) non-zero bits */
        !           100:
        !           101:   c = mpfr_round_raw (old_yp, yp, (mp_prec_t) (xn + 1) * BITS_PER_MP_LIMB,
        !           102:                      (MPFR_SIGN(x) < 0), MPFR_PREC(y), rnd_mode, &inexact);
        !           103:
        !           104:   cnt = BITS_PER_MP_LIMB - cnt;
        !           105:
        !           106:   if (c) /* rounded result is 1.0000000000000000... */
        !           107:     {
        !           108:       old_yp[yn-1] = GMP_LIMB_HIGHBIT;
        !           109:       cnt++;
        !           110:     }
        !           111:
1.1       maekawa   112:   TMP_FREE(marker);
1.1.1.2 ! ohara     113:
        !           114:   if (__mpfr_emax < MPFR_EMAX_MIN + cnt || MPFR_EXP(x) > __mpfr_emax - cnt)
        !           115:     return mpfr_set_overflow(y, rnd_mode, MPFR_SIGN(x));
        !           116:
        !           117:   MPFR_EXP(y) = MPFR_EXP(x) + cnt;
        !           118:   MPFR_SET_SAME_SIGN(y, x);
        !           119:
        !           120:   return inexact;
1.1       maekawa   121: }

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