summaryrefslogtreecommitdiff
path: root/set_si.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2000-04-14 07:33:46 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>2000-04-14 07:33:46 +0000
commitcffac6a428b743ca85d2f2e9115506d1abcc8897 (patch)
treeab735bb4ae086e875810c36af52272133249ec1c /set_si.c
parentc317a2a38e726c8478e69938971fce856f1d3f38 (diff)
downloadmpfr-cffac6a428b743ca85d2f2e9115506d1abcc8897.tar.gz
fixed pb when target precision is less than integer length
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@487 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'set_si.c')
-rw-r--r--set_si.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/set_si.c b/set_si.c
index fda046583..ee9d19993 100644
--- a/set_si.c
+++ b/set_si.c
@@ -35,7 +35,7 @@ mpfr_set_si(x, i, rnd_mode)
mp_rnd_t rnd_mode;
#endif
{
- unsigned long xn, cnt; mp_limb_t ai;
+ unsigned long xn, cnt; mp_limb_t ai, *xp;
if (i==0) { SET_ZERO(x); return; }
xn = (PREC(x)-1)/BITS_PER_MP_LIMB;
@@ -43,10 +43,23 @@ mpfr_set_si(x, i, rnd_mode)
count_leading_zeros(cnt, ai);
- x -> _mp_d[xn] = ai << cnt;
+ xp = MANT(x);
+ xp[xn] = ai << cnt;
/* don't forget to put zero in lower limbs */
- MPN_ZERO(MANT(x), xn);
- x -> _mp_exp = BITS_PER_MP_LIMB - cnt;
+ MPN_ZERO(xp, xn);
+
+ EXP(x) = BITS_PER_MP_LIMB - cnt;
+
+ /* round if PREC(x) smaller than length of i */
+ if (PREC(x) < mp_bits_per_limb-cnt) {
+ cnt = mpfr_round_raw(xp+xn, xp+xn, mp_bits_per_limb-cnt, (ai<0), PREC(x),
+ rnd_mode);
+ if (cnt) { /* special case 1.000...000 */
+ EXP(x)++;
+ xp[xn] = ((mp_limb_t) 1) << (BITS_PER_MP_LIMB-1);
+ }
+ }
+
/* warning: don't change the precision of x! */
if (i*MPFR_SIGN(x) < 0) CHANGE_SIGN(x);
@@ -63,16 +76,29 @@ mpfr_set_ui(x, i, rnd_mode)
mp_rnd_t rnd_mode;
#endif
{
- unsigned int xn, cnt;
+ unsigned int xn, cnt; mp_limb_t *xp;
if (i==0) { SET_ZERO(x); return; }
xn = (PREC(x)-1)/BITS_PER_MP_LIMB;
count_leading_zeros(cnt, (mp_limb_t) i);
- x -> _mp_d[xn] = ((mp_limb_t) i) << cnt;
+ xp = MANT(x);
+ xp[xn] = ((mp_limb_t) i) << cnt;
/* don't forget to put zero in lower limbs */
- MPN_ZERO(MANT(x), xn);
- x -> _mp_exp = BITS_PER_MP_LIMB - cnt;
+ MPN_ZERO(xp, xn);
+
+ EXP(x) = BITS_PER_MP_LIMB - cnt;
+
+ /* round if PREC(x) smaller than length of i */
+ if (PREC(x) < mp_bits_per_limb-cnt) {
+ cnt = mpfr_round_raw(xp+xn, xp+xn, mp_bits_per_limb-cnt, 0, PREC(x),
+ rnd_mode);
+ if (cnt) { /* special case 1.000...000 */
+ EXP(x)++;
+ xp[xn] = ((mp_limb_t) 1) << (BITS_PER_MP_LIMB-1);
+ }
+ }
+
/* warning: don't change the precision of x! */
if (MPFR_SIGN(x) < 0) CHANGE_SIGN(x);