summaryrefslogtreecommitdiff
path: root/sqrt.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-01-25 13:43:31 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-01-25 13:43:31 +0000
commit3c59e080c4af2f81c2d408d73b4828f42aba04b2 (patch)
tree47bb805a769444debc25aef6e8939b99a597bd69 /sqrt.c
parent8d22d7d086ae6cba6f979b89aeb6a9e7e1d5c53c (diff)
downloadmpfr-3c59e080c4af2f81c2d408d73b4828f42aba04b2.tar.gz
Code reformatted.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1670 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'sqrt.c')
-rw-r--r--sqrt.c300
1 files changed, 153 insertions, 147 deletions
diff --git a/sqrt.c b/sqrt.c
index 3da68d280..89082ad89 100644
--- a/sqrt.c
+++ b/sqrt.c
@@ -39,6 +39,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
int inexact = 0, t;
unsigned long cc = 0;
int can_round = 0;
+
TMP_DECL(marker0);
{
TMP_DECL (marker);
@@ -106,176 +107,181 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
to shift then.
*/
- TMP_MARK(marker0);
- if (odd_exp_u) /* Shift u one bit to the right */
- {
- if (MPFR_PREC(u) & (BITS_PER_MP_LIMB - 1))
- {
- up = TMP_ALLOC(usize*BYTES_PER_MP_LIMB);
- mpn_rshift(up, MPFR_MANT(u), usize, 1);
- }
- else
- {
- up = TMP_ALLOC((usize + 1)*BYTES_PER_MP_LIMB);
- if (mpn_rshift(up + 1, MPFR_MANT(u), usize, 1))
- up [0] = MP_LIMB_T_HIGHBIT;
- else up[0] = 0;
- usize++;
- }
- }
-
- MPFR_EXP(r) = MPFR_EXP(u) != MPFR_EMAX_MAX
- ? (MPFR_EXP(u) + odd_exp_u) / 2
- : (MPFR_EMAX_MAX - 1) / 2 + 1;
-
- do
- {
- TMP_MARK (marker);
-
- err = rsize*BITS_PER_MP_LIMB;
- if (rsize < usize) { err--; }
- if (err > rrsize * BITS_PER_MP_LIMB)
- { err = rrsize * BITS_PER_MP_LIMB; }
+ TMP_MARK(marker0);
+ if (odd_exp_u) /* Shift u one bit to the right */
+ {
+ if (MPFR_PREC(u) & (BITS_PER_MP_LIMB - 1))
+ {
+ up = TMP_ALLOC(usize * BYTES_PER_MP_LIMB);
+ mpn_rshift(up, MPFR_MANT(u), usize, 1);
+ }
+ else
+ {
+ up = TMP_ALLOC((usize + 1) * BYTES_PER_MP_LIMB);
+ if (mpn_rshift(up + 1, MPFR_MANT(u), usize, 1))
+ up[0] = MP_LIMB_T_HIGHBIT;
+ else
+ up[0] = 0;
+ usize++;
+ }
+ }
+
+ MPFR_EXP(r) = MPFR_EXP(u) != MPFR_EMAX_MAX
+ ? (MPFR_EXP(u) + odd_exp_u) / 2
+ : (MPFR_EMAX_MAX - 1) / 2 + 1;
+
+ do
+ {
+ TMP_MARK (marker);
+
+ err = rsize * BITS_PER_MP_LIMB;
+ if (rsize < usize)
+ err--;
+ if (err > rrsize * BITS_PER_MP_LIMB)
+ err = rrsize * BITS_PER_MP_LIMB;
- tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
- rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB);
- remp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ tmp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
+ rp = (mp_ptr) TMP_ALLOC (rrsize * BYTES_PER_MP_LIMB);
+ remp = (mp_ptr) TMP_ALLOC (rsize * BYTES_PER_MP_LIMB);
- if (usize >= rsize) {
- MPN_COPY (tmp, up + usize - rsize, rsize);
- }
- else {
- MPN_COPY (tmp + rsize - usize, up, usize);
- MPN_ZERO (tmp, rsize - usize);
- }
+ if (usize >= rsize)
+ {
+ MPN_COPY (tmp, up + usize - rsize, rsize);
+ }
+ else
+ {
+ MPN_COPY (tmp + rsize - usize, up, usize);
+ MPN_ZERO (tmp, rsize - usize);
+ }
- /* Do the real job */
+ /* Do the real job */
#ifdef DEBUG
- printf("Taking the sqrt of : ");
- for(k = rsize - 1; k >= 0; k--) {
- printf("+%lu*2^%lu",tmp[k],k*BITS_PER_MP_LIMB); }
- printf(".\n");
+ printf("Taking the sqrt of : ");
+ for(k = rsize - 1; k >= 0; k--)
+ printf("+%lu*2^%lu",tmp[k],k*BITS_PER_MP_LIMB);
+ printf(".\n");
#endif
- q_limb = mpn_sqrtrem (rp, remp, tmp, rsize);
+ q_limb = mpn_sqrtrem (rp, remp, tmp, rsize);
#ifdef DEBUG
- printf ("The result is : \n");
- printf ("sqrt : ");
- for (k = rrsize - 1; k >= 0; k--)
- printf ("%lu ", rp[k]);
- printf ("(inexact = %lu)\n", q_limb);
+ printf ("The result is : \n");
+ printf ("sqrt : ");
+ for (k = rrsize - 1; k >= 0; k--)
+ printf ("%lu ", rp[k]);
+ printf ("(inexact = %lu)\n", q_limb);
#endif
-
- can_round = mpfr_can_round_raw(rp, rrsize, 1, err,
- GMP_RNDZ, rnd_mode, MPFR_PREC(r));
- /* If we used all the limbs of both the dividend and the divisor,
- then we have the correct RNDZ rounding */
+ can_round = mpfr_can_round_raw(rp, rrsize, 1, err,
+ GMP_RNDZ, rnd_mode, MPFR_PREC(r));
- if (!can_round && (rsize < 2*usize))
- {
+ /* If we used all the limbs of both the dividend and the divisor,
+ then we have the correct RNDZ rounding */
+
+ if (!can_round && (rsize < 2*usize))
+ {
#ifdef DEBUG
- printf("Increasing the precision.\n");
+ printf("Increasing the precision.\n");
#endif
- TMP_FREE(marker);
- }
- }
- while (!can_round && (rsize < 2*usize)
- && (rsize += 2) && (rrsize ++));
+ TMP_FREE(marker);
+ }
+ }
+ while (!can_round && (rsize < 2*usize) && (rsize += 2) && (rrsize++));
#ifdef DEBUG
- printf ("can_round = %d\n", can_round);
+ printf ("can_round = %d\n", can_round);
#endif
- /* This part may be deplaced upper to avoid a few mpfr_can_round_raw */
- /* when the square root is exact. It is however very unprobable that */
- /* it would improve the behaviour of the present code on average. */
+ /* This part may be deplaced upper to avoid a few mpfr_can_round_raw */
+ /* when the square root is exact. It is however very unprobable that */
+ /* it would improve the behaviour of the present code on average. */
- if (!q_limb) /* the sqrtrem call was exact, possible exact square root */
- {
- /* if we have taken into account the whole of up */
- for (k = usize - rsize - 1; k >= 0; k ++)
- if (up[k]) break;
-
- if (k < 0)
- goto fin; /* exact square root ==> inexact = 0 */
- }
-
- if (can_round)
- {
- cc = mpfr_round_raw (rp, rp, err, 0, MPFR_PREC(r), rnd_mode, &inexact);
- if (!inexact) /* exact high part: inexact flag depends from remainder */
- inexact = -q_limb;
- rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
- }
- else
- /* Use the return value of sqrtrem to decide of the rounding */
- /* Note that at this point the sqrt has been computed */
- /* EXACTLY. */
- switch (rnd_mode)
+ if (!q_limb) /* the sqrtrem call was exact, possible exact square root */
{
- case GMP_RNDZ :
- case GMP_RNDD :
- inexact = -1; /* result is truncated */
- break;
-
- case GMP_RNDN :
- /* Not in the situation ...0 111111 */
- rw = (MPFR_PREC(r) + 1) & (BITS_PER_MP_LIMB - 1);
- if (rw)
- {
- rw = BITS_PER_MP_LIMB - rw;
- nw = 0;
- }
- else
- nw = 1;
- if ((rp[nw] >> rw) & 1 && /* Not 0111111111 */
- (q_limb || /* Nonzero remainder */
- (rw ? (rp[nw] >> (rw + 1)) & 1 :
- (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))) /* or even rounding */
- {
- cc = mpn_add_1 (rp + nw, rp + nw, rrsize, MP_LIMB_T_ONE << rw);
- inexact = 1;
- }
- else
- inexact = -1;
- break;
+ /* if we have taken into account the whole of up */
+ for (k = usize - rsize - 1; k >= 0; k++)
+ if (up[k] != 0)
+ break;
+
+ if (k < 0)
+ goto fin; /* exact square root ==> inexact = 0 */
+ }
+
+ if (can_round)
+ {
+ cc = mpfr_round_raw (rp, rp, err, 0, MPFR_PREC(r), rnd_mode, &inexact);
+ if (inexact == 0) /* exact high part: inex flag depends on remainder */
+ inexact = -q_limb;
+ rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ }
+ else
+ {
+ /* Use the return value of sqrtrem to decide of the rounding */
+ /* Note that at this point the sqrt has been computed */
+ /* EXACTLY. */
+ switch (rnd_mode)
+ {
+ case GMP_RNDZ :
+ case GMP_RNDD :
+ inexact = -1; /* result is truncated */
+ break;
+
+ case GMP_RNDN :
+ /* Not in the situation ...0 111111 */
+ rw = (MPFR_PREC(r) + 1) & (BITS_PER_MP_LIMB - 1);
+ if (rw != 0)
+ {
+ rw = BITS_PER_MP_LIMB - rw;
+ nw = 0;
+ }
+ else
+ nw = 1;
+ if ((rp[nw] >> rw) & 1 && /* Not 0111111111 */
+ (q_limb || /* Nonzero remainder */
+ (rw ? (rp[nw] >> (rw + 1)) & 1 :
+ (rp[nw] >> (BITS_PER_MP_LIMB - 1)) & 1))) /* or even r. */
+ {
+ cc = mpn_add_1 (rp + nw, rp + nw, rrsize, MP_LIMB_T_ONE << rw);
+ inexact = 1;
+ }
+ else
+ inexact = -1;
+ break;
- case GMP_RNDU:
- /* we should arrive here only when the result is inexact,
- i.e. either q_limb > 0 (the remainder from mpn_sqrtrem is non-zero)
- or up[0..usize-rsize-1] is non zero, thus we have to add one
- ulp, and inexact = 1 */
- inexact = 1;
- t = MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1);
- rsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
- if (t)
- cc = mpn_add_1 (rp + rrsize - rsize, rp + rrsize - rsize, rsize,
- MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - t));
- else
+ case GMP_RNDU:
+ /* we should arrive here only when the result is inexact, i.e.
+ either q_limb > 0 (the remainder from mpn_sqrtrem is non-zero)
+ or up[0..usize-rsize-1] is non zero, thus we have to add one
+ ulp, and inexact = 1 */
+ inexact = 1;
+ t = MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1);
+ rsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
cc = mpn_add_1 (rp + rrsize - rsize, rp + rrsize - rsize, rsize,
- MP_LIMB_T_ONE);
+ t != 0 ?
+ MP_LIMB_T_ONE << (BITS_PER_MP_LIMB - t) :
+ MP_LIMB_T_ONE);
+ }
}
- if (cc)
- {
- /* Is a shift necessary here? Isn't the result 1.0000...? */
- mpn_rshift (rp, rp, rrsize, 1);
- rp[rrsize-1] |= MP_LIMB_T_HIGHBIT;
- MPFR_EXP(r)++;
- }
-
- fin:
- rsize = rrsize;
- rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
- MPN_COPY(MPFR_MANT(r), rp + rsize - rrsize, rrsize);
-
- if (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1))
- MPFR_MANT(r) [0] &= ~((MP_LIMB_T_ONE << (BITS_PER_MP_LIMB -
- (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1) ;
-
- TMP_FREE (marker);
+ if (cc)
+ {
+ /* Is a shift necessary here? Isn't the result 1.0000...? */
+ mpn_rshift (rp, rp, rrsize, 1);
+ rp[rrsize-1] |= MP_LIMB_T_HIGHBIT;
+ MPFR_EXP(r)++;
+ }
+
+ fin:
+ rsize = rrsize;
+ rrsize = (MPFR_PREC(r) - 1)/BITS_PER_MP_LIMB + 1;
+ MPN_COPY(MPFR_MANT(r), rp + rsize - rrsize, rrsize);
+
+ if (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1))
+ MPFR_MANT(r)[0] &= ~((MP_LIMB_T_ONE <<
+ (BITS_PER_MP_LIMB -
+ (MPFR_PREC(r) & (BITS_PER_MP_LIMB - 1)))) - 1);
+
+ TMP_FREE (marker);
}
TMP_FREE(marker0);
return inexact;