diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-06-17 08:22:11 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 1999-06-17 08:22:11 +0000 |
commit | b3de1f8622a275ab2438fe6e820cecb51cdeefaa (patch) | |
tree | b22487f74c33e6102372c58b75c99341befbbeb5 /sub.c | |
parent | 67351f7209d3bebb554be2ab951e1c35232f0808 (diff) | |
download | mpfr-b3de1f8622a275ab2438fe6e820cecb51cdeefaa.tar.gz |
added TMP_DECL/TMP_MARK/TMP_FREE in mpfr_sub1 to deal with case
where destination=source
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@82 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sub.c')
-rw-r--r-- | sub.c | 14 |
1 files changed, 13 insertions, 1 deletions
@@ -54,6 +54,7 @@ mpfr_t a, b, c; unsigned char rnd_mode; int diff_exp; { mp_limb_t *ap, *bp, *cp, cc, c2; unsigned int an,bn,cn; int sh,dif,k,cancel,cancel1,cancel2; + TMP_DECL(marker); #ifdef DEBUG2 printf("b= "); if (SIGN(b)>=0) putchar(' '); @@ -66,9 +67,19 @@ mpfr_t a, b, c; unsigned char rnd_mode; int diff_exp; cancel = mpfr_cmp2(b, c); /* we have to take into account the first (PREC(a)+cancel) bits from b */ cancel1 = cancel/mp_bits_per_limb; cancel2 = cancel%mp_bits_per_limb; + TMP_MARK(marker); ap = MANT(a); bp = MANT(b); cp = MANT(c); + if (ap == bp) { + bp = (mp_ptr) TMP_ALLOC(ABSSIZE(b) * BYTES_PER_MP_LIMB); + MPN_COPY (bp, ap, ABSSIZE(b)); + } + else if (ap == cp) + { + cp = (mp_ptr) TMP_ALLOC (ABSSIZE(c) * BYTES_PER_MP_LIMB); + MPN_COPY(cp, ap, ABSSIZE(c)); + } an = (PREC(a)-1)/mp_bits_per_limb+1; /* number of significant limbs of a */ #ifdef DEBUG2 ap0=ap; ap1=ap+an-1; @@ -293,7 +304,7 @@ ck(ap, an, 21); if (cc==0 || cc==-1) cc=c2; } if ((long)cc>0) goto add_one_ulp; - else if ((long)cc<-1) return; /* the carry can be at most 1 */ + else if ((long)cc<-1) goto end_of_sub; /* the carry can be at most 1 */ else if (kc==0) goto round_b; /* else round c: go through */ case 3: /* only c to round */ @@ -410,6 +421,7 @@ mpfr_print_raw(a); putchar('\n'); #ifdef DEBUG2 printf("b-c="); if (SIGN(a)>0) putchar(' '); mpfr_print_raw(a); putchar('\n'); #endif + TMP_FREE(marker); return; } |