summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-01-22 00:45:44 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2002-01-22 00:45:44 +0000
commit67b58148a1817ff4539d4a9152dcc185f6509a0f (patch)
tree89edee7b60ad573d8ee295cfe4e5b445e5c032b4
parente643fca8156a8d7062a3c1f9709700f7c00f7833 (diff)
downloadmpfr-67b58148a1817ff4539d4a9152dcc185f6509a0f.tar.gz
MPFR_PREC_MAX redefined.
MPFR_INTPREC_MAX defined (internal maximum precision). Some integer overflow detection. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@1666 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--mpfr-impl.h6
-rw-r--r--mpfr.h6
-rw-r--r--mul.c9
-rw-r--r--sqrt.c44
4 files changed, 40 insertions, 25 deletions
diff --git a/mpfr-impl.h b/mpfr-impl.h
index bc917d5ca..8300e9e3b 100644
--- a/mpfr-impl.h
+++ b/mpfr-impl.h
@@ -30,6 +30,12 @@ typedef unsigned long int mp_size_unsigned_t;
#define MP_LIMB_T_ONE ((mp_limb_t) 1)
+#if (BITS_PER_MP_LIMB & (BITS_PER_MP_LIMB - 1))
+#error "BITS_PER_MP_LIMB must be a power of 2"
+#endif
+
+#define MPFR_INTPREC_MAX (ULONG_MAX & ~(unsigned long) (BITS_PER_MP_LIMB - 1))
+
/* Assertions */
/* Compile with -DWANT_ASSERT to check all assert statements */
diff --git a/mpfr.h b/mpfr.h
index 52ac36a88..d64d7c072 100644
--- a/mpfr.h
+++ b/mpfr.h
@@ -58,8 +58,10 @@ MA 02111-1307, USA. */
typedef unsigned long int mp_prec_t; /* easy to change if necessary */
#define MPFR_PREC_MIN 2
-#define MPFR_PREC_MAX ULONG_MAX
-typedef int mp_rnd_t; /* preferred to char */
+#define MPFR_PREC_MAX (ULONG_MAX >> 1)
+/* Limit mainly due to the multiplication code. */
+
+typedef int mp_rnd_t;
typedef struct {
mp_prec_t _mpfr_prec; /* WARNING : for the mpfr type, the precision */
diff --git a/mul.c b/mul.c
index 232efb95a..343eebc90 100644
--- a/mul.c
+++ b/mul.c
@@ -136,12 +136,13 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
bn = (bq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of b */
cn = (cq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of c */
- MPFR_ASSERTN(bq + cq >= bq); /* no integer overflow */
- tn = (bq + cq - 1) / BITS_PER_MP_LIMB + 1;
-
MPFR_ASSERTN((mp_size_unsigned_t) bn + cn <= MP_SIZE_T_MAX);
- k = bn + cn; /* effective nb of limbs used by b*c (=tn or tn+1) */
+ k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
+
+ MPFR_ASSERTN(bq + cq >= bq); /* no integer overflow */
+ tn = (bq + cq - 1) / BITS_PER_MP_LIMB + 1; /* <= k, thus no int overflow */
+ MPFR_ASSERTN(k <= ((size_t) -1) / BYTES_PER_MP_LIMB);
TMP_MARK(marker);
tmp = (mp_limb_t *) TMP_ALLOC((size_t) k * BYTES_PER_MP_LIMB);
diff --git a/sqrt.c b/sqrt.c
index c673642ac..3da68d280 100644
--- a/sqrt.c
+++ b/sqrt.c
@@ -34,6 +34,7 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
mp_size_t rsize;
mp_size_t err;
mp_limb_t q_limb;
+ int odd_exp_u;
long rw, nw, k;
int inexact = 0, t;
unsigned long cc = 0;
@@ -81,29 +82,32 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
MPFR_RET(0); /* zero is exact */
}
- up = MPFR_MANT(u);
- usize = (MPFR_PREC(u) - 1)/BITS_PER_MP_LIMB + 1;
+ up = MPFR_MANT(u);
+ usize = (MPFR_PREC(u) - 1)/BITS_PER_MP_LIMB + 1;
#ifdef DEBUG
- printf("Entering square root : ");
- for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); }
- printf(".\n");
+ printf("Entering square root : ");
+ for(k = usize - 1; k >= 0; k--) { printf("%lu ", up[k]); }
+ printf(".\n");
#endif
- /* Compare the mantissas */
-
- rsize = ((MPFR_PREC(r) + 2 + (MPFR_EXP(u) & 1))/BITS_PER_MP_LIMB + 1) << 1;
- rrsize = (MPFR_PREC(r) + 2 + (MPFR_EXP(u) & 1))/BITS_PER_MP_LIMB + 1;
- /* One extra bit is needed in order to get the square root with enough
- precision ; take one extra bit for rrsize in order to solve more
- easily the problem of rounding to nearest.
- Need to have 2*rrsize = rsize...
- Take one extra bit if the exponent of u is odd since we shall have
- to shift then.
- */
+ /* Compare the mantissas */
+
+ odd_exp_u = (unsigned int) MPFR_EXP(u) & 1;
+ MPFR_ASSERTN(MPFR_PREC(r) <= MPFR_INTPREC_MAX - 3);
+ rrsize = (MPFR_PREC(r) + 2 + odd_exp_u) / BITS_PER_MP_LIMB + 1;
+ MPFR_ASSERTN(rrsize <= MP_SIZE_T_MAX/2);
+ rsize = rrsize << 1;
+ /* One extra bit is needed in order to get the square root with enough
+ precision ; take one extra bit for rrsize in order to solve more
+ easily the problem of rounding to nearest.
+ Need to have 2*rrsize = rsize...
+ Take one extra bit if the exponent of u is odd since we shall have
+ to shift then.
+ */
TMP_MARK(marker0);
- if (MPFR_EXP(u) & 1) /* Shift u one bit to the right */
+ if (odd_exp_u) /* Shift u one bit to the right */
{
if (MPFR_PREC(u) & (BITS_PER_MP_LIMB - 1))
{
@@ -120,8 +124,10 @@ mpfr_sqrt (mpfr_ptr r, mpfr_srcptr u, mp_rnd_t rnd_mode)
}
}
- MPFR_EXP(r) = ((MPFR_EXP(u) + (MPFR_EXP(u) & 1)) / 2) ;
-
+ 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);