*** mul_ui.c 2000/12/18 09:01:58 1.23 --- mul_ui.c 2001/08/29 09:24:10 1.28 *************** *** 26,44 **** #include "mpfr.h" #include "mpfr-impl.h" void #if __STDC__ ! mpfr_mul_ui(mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) #else ! mpfr_mul_ui(y, x, u, rnd_mode) mpfr_ptr y; mpfr_srcptr x; unsigned long int u; mp_rnd_t rnd_mode; #endif { ! mp_limb_t carry, *my, *old_my, *my2; unsigned long c; ! unsigned long xsize, ysize, cnt, dif, ex, sh; TMP_DECL(marker); if (MPFR_IS_NAN(x)) --- 26,47 ---- #include "mpfr.h" #include "mpfr-impl.h" + #define ONE ((mp_limb_t) 1) + void #if __STDC__ ! mpfr_mul_ui (mpfr_ptr y, mpfr_srcptr x, unsigned long int u, mp_rnd_t rnd_mode) #else ! mpfr_mul_ui (y, x, u, rnd_mode) mpfr_ptr y; mpfr_srcptr x; unsigned long int u; mp_rnd_t rnd_mode; #endif { ! mp_limb_t carry, *my, *old_my, *my2; ! unsigned long xsize, ysize, cnt, dif, ex, c; ! long int sh; TMP_DECL(marker); if (MPFR_IS_NAN(x)) *************** *** 60,91 **** else { MPFR_SET_NAN(y); return; } } MPFR_CLEAR_FLAGS(y); TMP_MARK(marker); my = MPFR_MANT(y); ex = MPFR_EXP(x); ! ysize = (MPFR_PREC(y)-1)/BITS_PER_MP_LIMB + 1; ! xsize = (MPFR_PREC(x)-1)/BITS_PER_MP_LIMB + 1; ! old_my = my; ! if (ysize < xsize) { my = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB); ! dif=0; } ! else dif=ysize-xsize; ! carry = mpn_mul_1(my+dif, MPFR_MANT(x), xsize, u); ! MPN_ZERO(my, dif); /* WARNING: count_leading_zeros is undefined for carry=0 */ ! if (carry) count_leading_zeros(cnt, carry); ! else cnt=BITS_PER_MP_LIMB; ! /* Warning: the number of limbs used by x and the lower part ! of y may differ */ ! sh = (MPFR_PREC(x)+BITS_PER_MP_LIMB-1)/BITS_PER_MP_LIMB ! - (MPFR_PREC(y)+cnt-1)/BITS_PER_MP_LIMB; /* Warning: if all significant bits are in the carry, one has to be careful */ --- 63,104 ---- else { MPFR_SET_NAN(y); return; } } + if (MPFR_IS_ZERO(x) || !u) + { + MPFR_CLEAR_FLAGS(y); MPFR_SET_ZERO(y); return; + } + MPFR_CLEAR_FLAGS(y); TMP_MARK(marker); my = MPFR_MANT(y); ex = MPFR_EXP(x); ! ysize = (MPFR_PREC(y) - 1) / BITS_PER_MP_LIMB + 1; ! xsize = (MPFR_PREC(x) - 1) / BITS_PER_MP_LIMB + 1; ! old_my = my; ! if (ysize < xsize) ! { my = (mp_ptr) TMP_ALLOC (xsize * BYTES_PER_MP_LIMB); ! dif = 0; } ! else ! { ! dif = ysize - xsize; ! MPN_ZERO (my, dif); ! } ! carry = mpn_mul_1 (my + dif, MPFR_MANT(x), xsize, u); /* WARNING: count_leading_zeros is undefined for carry=0 */ ! if (carry) ! count_leading_zeros(cnt, carry); ! else ! cnt = BITS_PER_MP_LIMB; ! /* BITS_PER_MP_LIMB - cnt is the number of significant bits in the carry */ ! /* the first (BITS_PER_MP_LIMB-cnt) bits of the result are in carry, ! the remaining bits are in my[dif+xsize-1] .. my[dif] */ /* Warning: if all significant bits are in the carry, one has to be careful */ *************** *** 108,118 **** carry = 0; cnt = BITS_PER_MP_LIMB; } ! c = mpfr_round_raw(my+sh, my, MPFR_PREC(x), (MPFR_SIGN(x)<0), ! MPFR_PREC(y)-BITS_PER_MP_LIMB+cnt, rnd_mode); /* If cnt = 1111111111111 and c = 1 we shall get depressed */ ! if (c && (carry == (((mp_limb_t)1) << (cnt ? BITS_PER_MP_LIMB - cnt : 0)) - 1)) { cnt--; --- 121,142 ---- carry = 0; cnt = BITS_PER_MP_LIMB; } ! /* as we already have (BITS_PER_MP_LIMB-cnt) bits in carry, ! we need only prec(y) - (BITS_PER_MP_LIMB-cnt) more bits ! from those in my[dif+xsize-1] .. my[dif], ! and we want to store them in my[ysize-1] .. my[ysize]. ! Warning: the number of limbs used by x and the lower part ! of y may differ */ ! sh = ysize - (MPFR_PREC(y) + cnt - 1) / BITS_PER_MP_LIMB; ! c = mpfr_round_raw (my + sh, my + dif, MPFR_PREC(x), (MPFR_SIGN(x) < 0), ! MPFR_PREC(y) - BITS_PER_MP_LIMB + cnt, rnd_mode); ! ! /* now the high (BITS_PER_MP_LIMB-cnt) bits of the result are in carry, ! and the remaining (yprec-BITS_PER_MP_LIMB+cnt) ones in ! my[ysize-1] .. my[sh] */ /* If cnt = 1111111111111 and c = 1 we shall get depressed */ ! if (c && (carry == (ONE << (cnt ? BITS_PER_MP_LIMB - cnt : 0)) - 1)) { cnt--; *************** *** 122,134 **** else { /* Warning: mpn_rshift is undefined for shift=0 */ ! if (cnt!=BITS_PER_MP_LIMB) ! mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt); ! my[ysize - 1] |= (carry << cnt); } MPFR_EXP(y) = ex + BITS_PER_MP_LIMB - cnt; ! if (ysize < xsize) MPN_COPY(old_my, my, ysize); /* set sign */ ! if (MPFR_SIGN(y) * MPFR_SIGN(x) < 0) MPFR_CHANGE_SIGN(y); TMP_FREE(marker); } --- 146,160 ---- else { /* Warning: mpn_rshift is undefined for shift=0 */ ! if (cnt != BITS_PER_MP_LIMB) ! mpn_rshift(my, my, ysize, BITS_PER_MP_LIMB - cnt); ! my[ysize - 1] |= carry << cnt; } MPFR_EXP(y) = ex + BITS_PER_MP_LIMB - cnt; ! if (ysize < xsize) ! MPN_COPY(old_my, my, ysize); /* set sign */ ! if (MPFR_SIGN(y) * MPFR_SIGN(x) < 0) ! MPFR_CHANGE_SIGN(y); TMP_FREE(marker); }