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>