diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-07-02 16:13:14 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-07-02 16:13:14 +0000 |
commit | 8b73e2bba966f6d463d40a423d1b94374bfb2b76 (patch) | |
tree | deb59d7e98750e496ce638dca25060712357e3af /div_ui.c | |
parent | cedd2cb3addb943bd8932e8cc5ccb60d3b08c1f1 (diff) | |
download | mpfr-8b73e2bba966f6d463d40a423d1b94374bfb2b76.tar.gz |
fixed horrible hack yp[-1]
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@274 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'div_ui.c')
-rw-r--r-- | div_ui.c | 30 |
1 files changed, 19 insertions, 11 deletions
@@ -18,11 +18,13 @@ mpfr_div_ui(y, x, u, rnd_mode) unsigned char rnd_mode; #endif { - int xn, yn, dif, sh, i; mp_limb_t *xp, *yp, c, d; + int xn, yn, dif, sh, i; mp_limb_t *xp, *yp, *tmp, c, d; + TMP_DECL(marker); if (FLAG_NAN(x)) { SET_NAN(y); return 1; } if (u==0) { printf("infinity\n"); return 1; } + TMP_MARK(marker); xn = (PREC(x)-1)/BITS_PER_MP_LIMB + 1; yn = (PREC(y)-1)/BITS_PER_MP_LIMB + 1; @@ -33,24 +35,29 @@ mpfr_div_ui(y, x, u, rnd_mode) /* save limb yp[-1] that will be used to store an extra limb of the quotient */ - d = yp[-1]; dif = yn+1-xn; #ifdef DEBUG - printf("dif=%d u=%lu\n",dif,u); + printf("dif=%d u=%lu xn=%d\n",dif,u,xn); printf("x="); mpfr_print_raw(x); putchar('\n'); #endif + + /* we need to store yn+1 = xn + dif limbs of the quotient */ + if (ABSSIZE(y)>=yn+1) tmp=yp; + else tmp=TMP_ALLOC((yn+1)*BYTES_PER_MP_LIMB); + if (dif>=0) - c = mpn_divrem_1(yp-1, dif, xp, xn, u); + c = mpn_divrem_1(tmp, dif, xp, xn, (mp_limb_t) u); else /* dif < 0 i.e. xn > yn */ - c = mpn_divrem_1(yp-1, 0, xp-dif, yn, u); -#ifdef DEBUG -printf("y="); mpfr_print_raw(y); putchar('\n'); -#endif + c = mpn_divrem_1(tmp, 0, xp-dif, yn, (mp_limb_t) u); /* shift left to normalize */ - count_leading_zeros(sh, yp[yn-1]); - if (sh) { mpn_lshift(yp-1, yp-1, yn+1, sh); EXP(y) -= sh; } - yp[-1] = d; /* restore value of yp[-1] */ + count_leading_zeros(sh, tmp[yn]); + if (sh) { + mpn_lshift(yp, tmp+1, yn, sh); + yp[0] += tmp[0] >> (BITS_PER_MP_LIMB-sh); + EXP(y) -= sh; + } + else MPN_COPY(yp, tmp+1, yn); #ifdef DEBUG printf("y="); mpfr_print_raw(y); putchar('\n'); #endif @@ -61,6 +68,7 @@ printf("y="); mpfr_print_raw(y); putchar('\n'); d = *yp & (((mp_limb_t)1 << sh) - 1); *yp ^= d; /* set to zero lowest sh bits */ + TMP_FREE(marker); if ((c | d)==0) { for (i=0; i<-dif && xp[i]==0; i++); if (i>=-dif) return 0; /* result is exact */ |