int mpfr_set_si (mpfr_ptr x, long i, mp_rnd_t rnd_mode) { int inex; mp_size_t xn; unsigned int cnt, nbits; mp_limb_t ai, *xp; MPFR_CLEAR_FLAGS(x); if (i == 0) { MPFR_SET_ZERO(x); MPFR_SET_POS(x); MPFR_RET(0); } xn = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB; ai = SAFE_ABS(long, i); count_leading_zeros(cnt, ai); xp = MPFR_MANT(x); xp[xn] = ai << cnt; /* don't forget to put zero in lower limbs */ MPN_ZERO(xp, xn); /* set sign */ if ((i < 0) ^ (MPFR_SIGN(x) < 0)) MPFR_CHANGE_SIGN(x); MPFR_EXP(x) = nbits = BITS_PER_MP_LIMB - cnt; inex = mpfr_check_range(x, rnd_mode); if (inex) return inex; /* underflow or overflow */ /* round if MPFR_PREC(x) smaller than length of i */ if (MPFR_PREC(x) < nbits) { int carry; carry = mpfr_round_raw(xp+xn, xp+xn, nbits, (i < 0), MPFR_PREC(x), rnd_mode, &inex); if (carry) { mp_exp_t exp = MPFR_EXP(x); if (exp == __mpfr_emax) return mpfr_set_overflow(x, rnd_mode, (i < 0 ? -1 : 1)); MPFR_EXP(x)++; xp[xn] = GMP_LIMB_HIGHBIT; } } MPFR_RET(inex); }
int mpfr_set_si_2exp (mpfr_ptr x, long i, mp_exp_t e, mp_rnd_t rnd_mode) { if (i == 0) { MPFR_SET_ZERO (x); MPFR_SET_POS (x); MPFR_RET (0); } else { mp_size_t xn; unsigned int cnt, nbits; mp_limb_t ai, *xp; int inex = 0; /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */ ai = SAFE_ABS (unsigned long, i); MPFR_ASSERTN (SAFE_ABS (unsigned long, i) == ai); /* Position of the highest limb */ xn = (MPFR_PREC (x) - 1) / BITS_PER_MP_LIMB; count_leading_zeros (cnt, ai); MPFR_ASSERTD (cnt < BITS_PER_MP_LIMB); /* OK since i != 0 */ xp = MPFR_MANT(x); xp[xn] = ai << cnt; /* Zero the xn lower limbs. */ MPN_ZERO(xp, xn); MPFR_SET_SIGN (x, i < 0 ? MPFR_SIGN_NEG : MPFR_SIGN_POS); nbits = BITS_PER_MP_LIMB - cnt; e += nbits; /* exponent _before_ the rounding */ /* round if MPFR_PREC(x) smaller than length of i */ if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) && MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, i < 0, MPFR_PREC (x), rnd_mode, &inex))) { e++; xp[xn] = MPFR_LIMB_HIGHBIT; } MPFR_CLEAR_FLAGS (x); MPFR_EXP (x) = e; return mpfr_check_range (x, inex, rnd_mode); } }
int mpfr_set_ui_2exp (mpfr_ptr x, unsigned long i, mpfr_exp_t e, mpfr_rnd_t rnd_mode) { MPFR_SET_POS (x); if (i == 0) { MPFR_SET_ZERO (x); MPFR_RET (0); } else { mp_size_t xn; unsigned int cnt, nbits; mp_limb_t *xp; int inex = 0; /* FIXME: support int limbs (e.g. 16-bit limbs on 16-bit proc) */ MPFR_ASSERTD (i == (mp_limb_t) i); /* Position of the highest limb */ xn = (MPFR_PREC (x) - 1) / GMP_NUMB_BITS; count_leading_zeros (cnt, (mp_limb_t) i); MPFR_ASSERTD (cnt < GMP_NUMB_BITS); /* OK since i != 0 */ xp = MPFR_MANT(x); xp[xn] = ((mp_limb_t) i) << cnt; /* Zero the xn lower limbs. */ MPN_ZERO(xp, xn); nbits = GMP_NUMB_BITS - cnt; e += nbits; /* exponent _before_ the rounding */ /* round if MPFR_PREC(x) smaller than length of i */ if (MPFR_UNLIKELY (MPFR_PREC (x) < nbits) && MPFR_UNLIKELY (mpfr_round_raw (xp + xn, xp + xn, nbits, 0, MPFR_PREC (x), rnd_mode, &inex))) { e++; xp[xn] = MPFR_LIMB_HIGHBIT; } MPFR_EXP (x) = e; return mpfr_check_range (x, inex, rnd_mode); } }
int mpfr_sqr (mpfr_ptr a, mpfr_srcptr b, mpfr_rnd_t rnd_mode) { int cc, inexact; mpfr_exp_t ax; mp_limb_t *tmp; mp_limb_t b1; mpfr_prec_t bq; mp_size_t bn, tn; MPFR_TMP_DECL(marker); MPFR_LOG_FUNC (("x[%#R]=%R rnd=%d", b, b, rnd_mode), ("y[%#R]=%R inexact=%d", a, a, inexact)); /* deal with special cases */ if (MPFR_UNLIKELY(MPFR_IS_SINGULAR(b))) { if (MPFR_IS_NAN(b)) { MPFR_SET_NAN(a); MPFR_RET_NAN; } MPFR_SET_POS (a); if (MPFR_IS_INF(b)) MPFR_SET_INF(a); else ( MPFR_ASSERTD(MPFR_IS_ZERO(b)), MPFR_SET_ZERO(a) ); MPFR_RET(0); } ax = 2 * MPFR_GET_EXP (b); bq = MPFR_PREC(b); MPFR_ASSERTD (2 * bq > bq); /* PREC_MAX is /2 so no integer overflow */ bn = MPFR_LIMB_SIZE(b); /* number of limbs of b */ tn = 1 + (2 * bq - 1) / GMP_NUMB_BITS; /* number of limbs of square, 2*bn or 2*bn-1 */ MPFR_TMP_MARK(marker); tmp = (mp_limb_t *) MPFR_TMP_ALLOC((size_t) 2 * bn * BYTES_PER_MP_LIMB); /* Multiplies the mantissa in temporary allocated space */ mpn_sqr_n (tmp, MPFR_MANT(b), bn); b1 = tmp[2 * bn - 1]; /* now tmp[0]..tmp[2*bn-1] contains the product of both mantissa, with tmp[2*bn-1]>=2^(GMP_NUMB_BITS-2) */ b1 >>= GMP_NUMB_BITS - 1; /* msb from the product */ /* if the mantissas of b and c are uniformly distributed in ]1/2, 1], then their product is in ]1/4, 1/2] with probability 2*ln(2)-1 ~ 0.386 and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */ tmp += 2 * bn - tn; /* +0 or +1 */ if (MPFR_UNLIKELY(b1 == 0)) mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */ cc = mpfr_round_raw (MPFR_MANT (a), tmp, 2 * bq, 0, MPFR_PREC (a), rnd_mode, &inexact); /* cc = 1 ==> result is a power of two */ if (MPFR_UNLIKELY(cc)) MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT; MPFR_TMP_FREE(marker); { mpfr_exp_t ax2 = ax + (mpfr_exp_t) (b1 - 1 + cc); if (MPFR_UNLIKELY( ax2 > __gmpfr_emax)) return mpfr_overflow (a, rnd_mode, MPFR_SIGN_POS); if (MPFR_UNLIKELY( ax2 < __gmpfr_emin)) { /* In the rounding to the nearest mode, if the exponent of the exact result (i.e. before rounding, i.e. without taking cc into account) is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if both arguments are powers of 2), then round to zero. */ if (rnd_mode == MPFR_RNDN && (ax + (mpfr_exp_t) b1 < __gmpfr_emin || mpfr_powerof2_raw (b))) rnd_mode = MPFR_RNDZ; return mpfr_underflow (a, rnd_mode, MPFR_SIGN_POS); } MPFR_SET_EXP (a, ax2); MPFR_SET_POS (a); } MPFR_RET (inexact); }
static int mpfr_mul3 (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mpfr_rnd_t rnd_mode) { /* Old implementation */ int sign_product, cc, inexact; mpfr_exp_t ax; mp_limb_t *tmp; mp_limb_t b1; mpfr_prec_t bq, cq; mp_size_t bn, cn, tn, k; MPFR_TMP_DECL(marker); /* deal with special cases */ if (MPFR_ARE_SINGULAR(b,c)) { if (MPFR_IS_NAN(b) || MPFR_IS_NAN(c)) { MPFR_SET_NAN(a); MPFR_RET_NAN; } sign_product = MPFR_MULT_SIGN( MPFR_SIGN(b) , MPFR_SIGN(c) ); if (MPFR_IS_INF(b)) { if (MPFR_IS_INF(c) || MPFR_NOTZERO(c)) { MPFR_SET_SIGN(a,sign_product); MPFR_SET_INF(a); MPFR_RET(0); /* exact */ } else { MPFR_SET_NAN(a); MPFR_RET_NAN; } } else if (MPFR_IS_INF(c)) { if (MPFR_NOTZERO(b)) { MPFR_SET_SIGN(a, sign_product); MPFR_SET_INF(a); MPFR_RET(0); /* exact */ } else { MPFR_SET_NAN(a); MPFR_RET_NAN; } } else { MPFR_ASSERTD(MPFR_IS_ZERO(b) || MPFR_IS_ZERO(c)); MPFR_SET_SIGN(a, sign_product); MPFR_SET_ZERO(a); MPFR_RET(0); /* 0 * 0 is exact */ } } sign_product = MPFR_MULT_SIGN( MPFR_SIGN(b) , MPFR_SIGN(c) ); ax = MPFR_GET_EXP (b) + MPFR_GET_EXP (c); bq = MPFR_PREC(b); cq = MPFR_PREC(c); MPFR_ASSERTD(bq+cq > bq); /* PREC_MAX is /2 so no integer overflow */ bn = (bq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of b */ cn = (cq+GMP_NUMB_BITS-1)/GMP_NUMB_BITS; /* number of limbs of c */ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */ tn = (bq + cq + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS; /* <= k, thus no int overflow */ MPFR_ASSERTD(tn <= k); /* Check for no size_t overflow*/ MPFR_ASSERTD((size_t) k <= ((size_t) -1) / BYTES_PER_MP_LIMB); MPFR_TMP_MARK(marker); tmp = (mp_limb_t *) MPFR_TMP_ALLOC((size_t) k * BYTES_PER_MP_LIMB); /* multiplies two mantissa in temporary allocated space */ b1 = (MPFR_LIKELY(bn >= cn)) ? mpn_mul (tmp, MPFR_MANT(b), bn, MPFR_MANT(c), cn) : mpn_mul (tmp, MPFR_MANT(c), cn, MPFR_MANT(b), bn); /* now tmp[0]..tmp[k-1] contains the product of both mantissa, with tmp[k-1]>=2^(GMP_NUMB_BITS-2) */ b1 >>= GMP_NUMB_BITS - 1; /* msb from the product */ /* if the mantissas of b and c are uniformly distributed in ]1/2, 1], then their product is in ]1/4, 1/2] with probability 2*ln(2)-1 ~ 0.386 and in [1/2, 1] with probability 2-2*ln(2) ~ 0.614 */ tmp += k - tn; if (MPFR_UNLIKELY(b1 == 0)) mpn_lshift (tmp, tmp, tn, 1); /* tn <= k, so no stack corruption */ cc = mpfr_round_raw (MPFR_MANT (a), tmp, bq + cq, MPFR_IS_NEG_SIGN(sign_product), MPFR_PREC (a), rnd_mode, &inexact); /* cc = 1 ==> result is a power of two */ if (MPFR_UNLIKELY(cc)) MPFR_MANT(a)[MPFR_LIMB_SIZE(a)-1] = MPFR_LIMB_HIGHBIT; MPFR_TMP_FREE(marker); { mpfr_exp_t ax2 = ax + (mpfr_exp_t) (b1 - 1 + cc); if (MPFR_UNLIKELY( ax2 > __gmpfr_emax)) return mpfr_overflow (a, rnd_mode, sign_product); if (MPFR_UNLIKELY( ax2 < __gmpfr_emin)) { /* In the rounding to the nearest mode, if the exponent of the exact result (i.e. before rounding, i.e. without taking cc into account) is < __gmpfr_emin - 1 or the exact result is a power of 2 (i.e. if both arguments are powers of 2), then round to zero. */ if (rnd_mode == MPFR_RNDN && (ax + (mpfr_exp_t) b1 < __gmpfr_emin || (mpfr_powerof2_raw (b) && mpfr_powerof2_raw (c)))) rnd_mode = MPFR_RNDZ; return mpfr_underflow (a, rnd_mode, sign_product); } MPFR_SET_EXP (a, ax2); MPFR_SET_SIGN(a, sign_product); } MPFR_RET (inexact); }
int mpfr_frac (mpfr_ptr r, mpfr_srcptr u, mpfr_rnd_t rnd_mode) { mpfr_exp_t re, ue; mpfr_prec_t uq; mp_size_t un, tn, t0; mp_limb_t *up, *tp, k; int sh; mpfr_t tmp; mpfr_ptr t; int inex; MPFR_SAVE_EXPO_DECL (expo); /* Special cases */ if (MPFR_UNLIKELY(MPFR_IS_NAN(u))) { MPFR_SET_NAN(r); MPFR_RET_NAN; } else if (MPFR_UNLIKELY(MPFR_IS_INF(u) || mpfr_integer_p (u))) { MPFR_SET_SAME_SIGN(r, u); MPFR_SET_ZERO(r); MPFR_RET(0); /* zero is exact */ } ue = MPFR_GET_EXP (u); if (ue <= 0) /* |u| < 1 */ return mpfr_set (r, u, rnd_mode); /* Now |u| >= 1, meaning that an overflow is not possible. */ uq = MPFR_PREC(u); un = (uq - 1) / GMP_NUMB_BITS; /* index of most significant limb */ un -= (mp_size_t) (ue / GMP_NUMB_BITS); /* now the index of the MSL containing bits of the fractional part */ up = MPFR_MANT(u); sh = ue % GMP_NUMB_BITS; k = up[un] << sh; /* the first bit of the fractional part is the MSB of k */ if (k != 0) { int cnt; count_leading_zeros(cnt, k); /* first bit 1 of the fractional part -> MSB of the number */ re = -cnt; sh += cnt; MPFR_ASSERTN (sh < GMP_NUMB_BITS); k <<= cnt; } else { re = sh - GMP_NUMB_BITS; /* searching for the first bit 1 (exists since u isn't an integer) */ while (up[--un] == 0) re -= GMP_NUMB_BITS; MPFR_ASSERTN(un >= 0); k = up[un]; count_leading_zeros(sh, k); re -= sh; k <<= sh; } /* The exponent of r will be re */ /* un: index of the limb of u that contains the first bit 1 of the FP */ t = (mp_size_t) (MPFR_PREC(r) - 1) / GMP_NUMB_BITS < un ? (mpfr_init2 (tmp, (un + 1) * GMP_NUMB_BITS), tmp) : r; /* t has enough precision to contain the fractional part of u */ /* If we use a temporary variable, we take the non-significant bits of u into account, because of the mpn_lshift below. */ MPFR_SET_SAME_SIGN(t, u); /* Put the fractional part of u into t */ tn = (MPFR_PREC(t) - 1) / GMP_NUMB_BITS; MPFR_ASSERTN(tn >= un); t0 = tn - un; tp = MPFR_MANT(t); if (sh == 0) MPN_COPY_DECR(tp + t0, up, un + 1); else /* warning: un may be 0 here */ tp[tn] = k | ((un) ? mpn_lshift (tp + t0, up, un, sh) : (mp_limb_t) 0); if (t0 > 0) MPN_ZERO(tp, t0); MPFR_SAVE_EXPO_MARK (expo); if (t != r) { /* t is tmp */ MPFR_EXP (t) = 0; /* should be re, but not necessarily in the range */ inex = mpfr_set (r, t, rnd_mode); /* no underflow */ mpfr_clear (t); MPFR_EXP (r) += re; } else { /* There may be remaining non-significant bits in t (= r). */ int carry; MPFR_EXP (r) = re; carry = mpfr_round_raw (tp, tp, (mpfr_prec_t) (tn + 1) * GMP_NUMB_BITS, MPFR_IS_NEG (r), MPFR_PREC (r), rnd_mode, &inex); if (carry) { tp[tn] = MPFR_LIMB_HIGHBIT; MPFR_EXP (r) ++; } } MPFR_SAVE_EXPO_FREE (expo); return mpfr_check_range (r, inex, rnd_mode); }
int mpfr_set_f (mpfr_ptr y, mpf_srcptr x, mpfr_rnd_t rnd_mode) { mp_limb_t *my, *mx, *tmp; unsigned long cnt, sx, sy; int inexact, carry = 0; MPFR_TMP_DECL(marker); sx = ABS(SIZ(x)); /* number of limbs of the mantissa of x */ if (sx == 0) /* x is zero */ { MPFR_SET_ZERO(y); MPFR_SET_POS(y); return 0; /* 0 is exact */ } if (SIZ(x) * MPFR_FROM_SIGN_TO_INT(MPFR_SIGN(y)) < 0) MPFR_CHANGE_SIGN (y); sy = MPFR_LIMB_SIZE (y); my = MPFR_MANT(y); mx = PTR(x); count_leading_zeros(cnt, mx[sx - 1]); if (sy <= sx) /* we may have to round even when sy = sx */ { unsigned long xprec = sx * GMP_NUMB_BITS; MPFR_TMP_MARK(marker); tmp = MPFR_TMP_LIMBS_ALLOC (sx); if (cnt) mpn_lshift (tmp, mx, sx, cnt); else /* FIXME: we may avoid the copy here, and directly call mpfr_round_raw on mx instead of tmp */ MPN_COPY (tmp, mx, sx); carry = mpfr_round_raw (my, tmp, xprec, (SIZ(x) < 0), MPFR_PREC(y), rnd_mode, &inexact); if (MPFR_UNLIKELY(carry)) /* result is a power of two */ my[sy - 1] = MPFR_LIMB_HIGHBIT; MPFR_TMP_FREE(marker); } else { if (cnt) mpn_lshift (my + sy - sx, mx, sx, cnt); else MPN_COPY (my + sy - sx, mx, sx); MPN_ZERO(my, sy - sx); /* no rounding necessary, since y has a larger mantissa */ inexact = 0; } /* warning: EXP(x) * GMP_NUMB_BITS may exceed the maximal exponent */ if (EXP(x) > 1 + (__gmpfr_emax - 1) / GMP_NUMB_BITS) { /* EXP(x) >= 2 + floor((__gmpfr_emax-1)/GMP_NUMB_BITS) EXP(x) >= 2 + (__gmpfr_emax - GMP_NUMB_BITS) / GMP_NUMB_BITS >= 1 + __gmpfr_emax / GMP_NUMB_BITS EXP(x) * GMP_NUMB_BITS >= __gmpfr_emax + GMP_NUMB_BITS Since 0 <= cnt <= GMP_NUMB_BITS-1, and 0 <= carry <= 1, we have then EXP(x) * GMP_NUMB_BITS - cnt + carry > __gmpfr_emax */ return mpfr_overflow (y, rnd_mode, MPFR_SIGN (y)); } else { /* Do not use MPFR_SET_EXP as the exponent may be out of range. */ MPFR_EXP (y) = EXP (x) * GMP_NUMB_BITS - (mpfr_exp_t) cnt + carry; } return mpfr_check_range (y, inexact, rnd_mode); }