summaryrefslogtreecommitdiff
path: root/div_ui.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>1999-07-02 16:13:14 +0000
committerzimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4>1999-07-02 16:13:14 +0000
commit8b73e2bba966f6d463d40a423d1b94374bfb2b76 (patch)
treedeb59d7e98750e496ce638dca25060712357e3af /div_ui.c
parentcedd2cb3addb943bd8932e8cc5ccb60d3b08c1f1 (diff)
downloadmpfr-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.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/div_ui.c b/div_ui.c
index 489740df6..700e7d19b 100644
--- a/div_ui.c
+++ b/div_ui.c
@@ -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 */