summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortege <tege@gmplib.org>2002-05-06 15:05:24 +0200
committertege <tege@gmplib.org>2002-05-06 15:05:24 +0200
commit0e6c3fe79785bac780c57613a11a333ec6649453 (patch)
tree16e8ee3cca8e35f57f42e78aebd8ad08ad039997
parent9a2cd598e3e9ea6f035ddc74e4c0bbc91542c459 (diff)
downloadgmp-0e6c3fe79785bac780c57613a11a333ec6649453.tar.gz
Nailify.
-rw-r--r--mpf/cmp_si.c44
-rw-r--r--mpf/cmp_ui.c33
-rw-r--r--mpf/div.c3
-rw-r--r--mpf/div_2exp.c11
-rw-r--r--mpf/div_ui.c15
-rw-r--r--mpf/eq.c8
-rw-r--r--mpf/get_d.c2
-rw-r--r--mpf/get_d_2exp.c2
-rw-r--r--mpf/get_si.c20
-rw-r--r--mpf/get_str.c23
-rw-r--r--mpf/get_ui.c4
11 files changed, 115 insertions, 50 deletions
diff --git a/mpf/cmp_si.c b/mpf/cmp_si.c
index d0a1c4c63..6266b953a 100644
--- a/mpf/cmp_si.c
+++ b/mpf/cmp_si.c
@@ -23,24 +23,25 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
int
-mpf_cmp_si (mpf_srcptr u, long int vslimb)
+mpf_cmp_si (mpf_srcptr u, long int vval)
{
mp_srcptr up;
mp_size_t usize;
mp_exp_t uexp;
+ mp_limb_t ulimb;
int usign;
uexp = u->_mp_exp;
usize = u->_mp_size;
/* 1. Are the signs different? */
- if ((usize < 0) == (vslimb < 0)) /* don't use xor, type size may differ */
+ if ((usize < 0) == (vval < 0)) /* don't use xor, type size may differ */
{
/* U and V are both non-negative or both negative. */
if (usize == 0)
- /* vslimb >= 0 */
- return -(vslimb != 0);
- if (vslimb == 0)
+ /* vval >= 0 */
+ return -(vval != 0);
+ if (vval == 0)
/* usize >= 0 */
return usize != 0;
/* Fall out. */
@@ -54,37 +55,52 @@ mpf_cmp_si (mpf_srcptr u, long int vslimb)
/* U and V have the same sign and are both non-zero. */
usign = usize >= 0 ? 1 : -1;
+ usize = ABS (usize);
+ vval = ABS (vval);
/* 2. Are the exponents different (V's exponent == 1)? */
+#if GMP_NAIL_BITS != 0
+ if (uexp > 1 + (vval > GMP_NUMB_MAX))
+ return usign;
+ if (uexp < 1 + (vval > GMP_NUMB_MAX))
+ return -usign;
+#else
if (uexp > 1)
return usign;
if (uexp < 1)
return -usign;
-
- usize = ABS (usize);
- vslimb = ABS (vslimb);
+#endif
up = u->_mp_d;
+ ulimb = up[usize - 1];
+#if GMP_NAIL_BITS != 0
+ if (usize >= 2 && uexp == 2)
+ {
+ if ((ulimb >> GMP_NAIL_BITS) != 0)
+ return 1;
+ ulimb = (ulimb << GMP_NUMB_BITS) | up[usize - 2];
+ usize--;
+ }
+#endif
+ usize--;
+
/* 3. Compare the most significant mantissa limb with V. */
- if (up[usize - 1] > (unsigned long) vslimb)
+ if (ulimb > (unsigned long) vval)
return usign;
- else if (up[usize - 1] < (unsigned long) vslimb)
+ else if (ulimb < (unsigned long) vval)
return -usign;
-#define STRICT_MPF_NORMALIZATION 0
-#if ! STRICT_MPF_NORMALIZATION
/* Ignore zeroes at the low end of U. */
while (*up == 0)
{
up++;
usize--;
}
-#endif
/* 4. Now, if the number of limbs are different, we have a difference
since we have made sure the trailing limbs are not zero. */
- if (usize > 1)
+ if (usize > 0)
return usign;
/* Wow, we got zero even if we tried hard to avoid it. */
diff --git a/mpf/cmp_ui.c b/mpf/cmp_ui.c
index cbb17bbac..47ca597a4 100644
--- a/mpf/cmp_ui.c
+++ b/mpf/cmp_ui.c
@@ -23,11 +23,12 @@ MA 02111-1307, USA. */
#include "gmp-impl.h"
int
-mpf_cmp_ui (mpf_srcptr u, unsigned long int vlimb)
+mpf_cmp_ui (mpf_srcptr u, unsigned long int vval)
{
mp_srcptr up;
mp_size_t usize;
mp_exp_t uexp;
+ mp_limb_t ulimb;
uexp = u->_mp_exp;
usize = u->_mp_size;
@@ -37,36 +38,52 @@ mpf_cmp_ui (mpf_srcptr u, unsigned long int vlimb)
return -1;
/* We rely on usize being non-negative in the code that follows. */
- if (vlimb == 0)
+ if (vval == 0)
return usize != 0;
/* 2. Are the exponents different (V's exponent == 1)? */
+#if GMP_NAIL_BITS != 0
+ if (uexp > 1 + (vval > GMP_NUMB_MAX))
+ return 1;
+ if (uexp < 1 + (vval > GMP_NUMB_MAX))
+ return -1;
+#else
if (uexp > 1)
return 1;
if (uexp < 1)
return -1;
+#endif
up = u->_mp_d;
+ ulimb = up[usize - 1];
+#if GMP_NAIL_BITS != 0
+ if (usize >= 2 && uexp == 2)
+ {
+ if ((ulimb >> GMP_NAIL_BITS) != 0)
+ return 1;
+ ulimb = (ulimb << GMP_NUMB_BITS) | up[usize - 2];
+ usize--;
+ }
+#endif
+ usize--;
+
/* 3. Compare the most significant mantissa limb with V. */
- if (up[usize - 1] > vlimb)
+ if (ulimb > vval)
return 1;
- else if (up[usize - 1] < vlimb)
+ else if (ulimb < vval)
return -1;
-#define STRICT_MPF_NORMALIZATION 0
-#if ! STRICT_MPF_NORMALIZATION
/* Ignore zeroes at the low end of U. */
while (*up == 0)
{
up++;
usize--;
}
-#endif
/* 4. Now, if the number of limbs are different, we have a difference
since we have made sure the trailing limbs are not zero. */
- if (usize > 1)
+ if (usize > 0)
return 1;
/* Wow, we got zero even if we tried hard to avoid it. */
diff --git a/mpf/div.c b/mpf/div.c
index c8ce73442..0f298a554 100644
--- a/mpf/div.c
+++ b/mpf/div.c
@@ -83,13 +83,14 @@ mpf_div (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
/* Normalize the divisor and the dividend. */
- if (! (vp[vsize-1] & MP_LIMB_T_HIGHBIT))
+ if ((vp[vsize-1] & GMP_NUMB_HIGHBIT) == 0)
{
mp_ptr tmp;
mp_limb_t nlimb;
unsigned normalization_steps;
count_leading_zeros (normalization_steps, vp[vsize - 1]);
+ normalization_steps -= GMP_NAIL_BITS;
/* Shift up the divisor setting the most significant bit of
the most significant limb. Use temporary storage not to clobber
diff --git a/mpf/div_2exp.c b/mpf/div_2exp.c
index 870abefe3..6f70aedd5 100644
--- a/mpf/div_2exp.c
+++ b/mpf/div_2exp.c
@@ -44,7 +44,7 @@ mpf_div_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp)
abs_usize = ABS (usize);
up = u->_mp_d;
- if (exp % BITS_PER_MP_LIMB == 0)
+ if (exp % GMP_NUMB_BITS == 0)
{
prec++; /* retain more precision here as we don't need
to account for carry-out here */
@@ -55,7 +55,7 @@ mpf_div_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp)
}
if (rp != up)
MPN_COPY_INCR (rp, up, abs_usize);
- r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB;
+ r->_mp_exp = uexp - exp / GMP_NUMB_BITS;
}
else
{
@@ -68,19 +68,20 @@ mpf_div_2exp (mpf_ptr r, mpf_srcptr u, unsigned long int exp)
/* Use mpn_rshift since mpn_lshift operates downwards, and we
therefore would clobber part of U before using that part, in case
R is the same variable as U. */
- cy_limb = mpn_rshift (rp + 1, up, abs_usize, exp % BITS_PER_MP_LIMB);
+ cy_limb = mpn_rshift (rp + 1, up, abs_usize, exp % GMP_NUMB_BITS);
rp[0] = cy_limb;
adj = rp[abs_usize] != 0;
}
else
{
- cy_limb = mpn_lshift (rp, up, abs_usize, (-exp) % BITS_PER_MP_LIMB);
+ cy_limb = mpn_lshift (rp, up, abs_usize,
+ GMP_NUMB_BITS - exp % GMP_NUMB_BITS);
rp[abs_usize] = cy_limb;
adj = cy_limb != 0;
}
abs_usize += adj;
- r->_mp_exp = uexp - exp / BITS_PER_MP_LIMB - 1 + adj;
+ r->_mp_exp = uexp - exp / GMP_NUMB_BITS - 1 + adj;
}
r->_mp_size = usize >= 0 ? abs_usize : -abs_usize;
}
diff --git a/mpf/div_ui.c b/mpf/div_ui.c
index 74405afd7..8aed3dbb7 100644
--- a/mpf/div_ui.c
+++ b/mpf/div_ui.c
@@ -36,6 +36,21 @@ mpf_div_ui (mpf_ptr r, mpf_srcptr u, unsigned long int v)
mp_exp_t rexp;
TMP_DECL (marker);
+#if GMP_NAIL_BITS != 0
+ if (v > GMP_NUMB_MAX)
+ {
+ mpf_t vf;
+ mp_limb_t vl[2];
+ SIZ(vf) = 2;
+ EXP(vf) = 2;
+ PTR(vf) = vl;
+ vl[0] = v & GMP_NUMB_MASK;
+ vl[1] = v >> GMP_NUMB_BITS;
+ mpf_div (r, u, vf);
+ return;
+ }
+#endif
+
usize = u->_mp_size;
sign_quotient = usize;
usize = ABS (usize);
diff --git a/mpf/eq.c b/mpf/eq.c
index 52dd366ef..e33f51351 100644
--- a/mpf/eq.c
+++ b/mpf/eq.c
@@ -83,13 +83,13 @@ mpf_eq (mpf_srcptr u, mpf_srcptr v, unsigned long int n_bits)
if (usize > vsize)
{
- if (vsize * BITS_PER_MP_LIMB < n_bits)
+ if (vsize * GMP_NUMB_BITS < n_bits)
return 0; /* surely too different */
size = vsize;
}
else if (vsize > usize)
{
- if (usize * BITS_PER_MP_LIMB < n_bits)
+ if (usize * GMP_NUMB_BITS < n_bits)
return 0; /* surely too different */
size = usize;
}
@@ -98,8 +98,8 @@ mpf_eq (mpf_srcptr u, mpf_srcptr v, unsigned long int n_bits)
size = usize;
}
- if (size > (n_bits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB)
- size = (n_bits + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
+ if (size > (n_bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS)
+ size = (n_bits + GMP_NUMB_BITS - 1) / GMP_NUMB_BITS;
up += usize - size;
vp += vsize - size;
diff --git a/mpf/get_d.c b/mpf/get_d.c
index 42220d54a..d2a56e2af 100644
--- a/mpf/get_d.c
+++ b/mpf/get_d.c
@@ -43,7 +43,7 @@ mpf_get_d (mpf_srcptr src)
for (i = 2; i <= n_limbs_to_use; i++)
res = res * MP_BASE_AS_DOUBLE + qp[size - i];
- res = __gmp_scale2 (res, (EXP(src) - n_limbs_to_use) * BITS_PER_MP_LIMB);
+ res = __gmp_scale2 (res, (EXP(src) - n_limbs_to_use) * GMP_NUMB_BITS);
return negative ? -res : res;
}
diff --git a/mpf/get_d_2exp.c b/mpf/get_d_2exp.c
index 92e3a2edc..cc5aced62 100644
--- a/mpf/get_d_2exp.c
+++ b/mpf/get_d_2exp.c
@@ -49,7 +49,7 @@ mpf_get_d_2exp (signed long int *exp2, mpf_srcptr src)
for (i = 1; i < n_limbs_to_use; i++)
res = (res + qp[i]) / MP_BASE_AS_DOUBLE;
count_leading_zeros (cnt, qp[n_limbs_to_use - 1]);
- *exp2 = EXP(src) * BITS_PER_MP_LIMB - cnt;
+ *exp2 = EXP(src) * GMP_NUMB_BITS - cnt + GMP_NAIL_BITS;
res = res * ((mp_limb_t) 1 << cnt);
return negative ? -res : res;
diff --git a/mpf/get_si.c b/mpf/get_si.c
index 9246685c3..006966df0 100644
--- a/mpf/get_si.c
+++ b/mpf/get_si.c
@@ -35,9 +35,10 @@ MA 02111-1307, USA.
long
mpf_get_si (mpf_srcptr f)
{
- mp_exp_t exp;
- int size, abs_size;
- long n;
+ mp_exp_t exp;
+ mp_size_t size, abs_size;
+ mp_ptr fp;
+ mp_limb_t fl;
size = SIZ (f);
if (size == 0)
@@ -53,10 +54,17 @@ mpf_get_si (mpf_srcptr f)
if (exp > abs_size)
return 0L;
- n = (long) PTR(f)[abs_size-exp];
+ fp = PTR(f);
+ fl = fp[abs_size - exp];
+
+#if GMP_NAIL_BITS != 0
+ if (ULONG_MAX > GMP_NUMB_MAX != 0 && exp > 1)
+ fl |= fp[abs_size - exp + 1] << GMP_NUMB_BITS;
+#endif
+
if (size > 0)
- return n & LONG_MAX;
+ return fl & LONG_MAX;
else
/* this form necessary to correctly handle -0x80..00 */
- return ~ ((n - 1) & LONG_MAX);
+ return ~ ((fl - 1) & LONG_MAX);
}
diff --git a/mpf/get_str.c b/mpf/get_str.c
index c57fc0f5c..b61e230ef 100644
--- a/mpf/get_str.c
+++ b/mpf/get_str.c
@@ -92,7 +92,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
desired. We could probably decrease both this, and avoid the +1
for setting prec above. */
prec = 2 + (mp_size_t)
- (n_digits / (BITS_PER_MP_LIMB * __mp_bases[base].chars_per_bit_exactly));
+ (n_digits / (GMP_NUMB_BITS * __mp_bases[base].chars_per_bit_exactly));
#endif
}
@@ -136,7 +136,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
#endif
count_leading_zeros (cnt, up[usize - 1]);
- exp_in_base = (((double) uexp * BITS_PER_MP_LIMB - cnt)
+ exp_in_base = (((double) uexp * GMP_NUMB_BITS - cnt + GMP_NAIL_BITS)
* __mp_bases[base].chars_per_bit_exactly);
exp_in_base += 1;
@@ -147,7 +147,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
rp[0] = base;
rsize = 1;
count_leading_zeros (cnt, exp_in_base);
- for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--)
{
mpn_sqr_n (tp, rp, rsize);
rsize = 2 * rsize;
@@ -171,6 +171,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
}
count_leading_zeros (cnt, rp[rsize - 1]);
+ cnt -= GMP_NAIL_BITS;
if (cnt != 0)
{
mpn_lshift (rp, rp, rsize, cnt);
@@ -239,7 +240,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
uexp = -uexp;
count_leading_zeros (cnt, up[usize - 1]);
- exp_in_base = (((double) uexp * BITS_PER_MP_LIMB + cnt - 1)
+ exp_in_base = (((double) uexp * GMP_NUMB_BITS + cnt - GMP_NAIL_BITS - 1)
* __mp_bases[base].chars_per_bit_exactly);
if (exp_in_base < 0)
exp_in_base = 0;
@@ -253,7 +254,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
rp[0] = base;
rsize = 1;
count_leading_zeros (cnt, exp_in_base);
- for (i = BITS_PER_MP_LIMB - cnt - 2; i >= 0; i--)
+ for (i = GMP_LIMB_BITS - cnt - 2; i >= 0; i--)
{
mpn_sqr_n (tp, rp, rsize);
rsize = 2 * rsize;
@@ -305,7 +306,7 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
if (big_base < 10) /* logarithm of base when power of two */
{
int logbase = big_base;
- if (dig_per_u * logbase == BITS_PER_MP_LIMB)
+ if (dig_per_u * logbase == GMP_NUMB_BITS)
dig_per_u--;
big_base = (mp_limb_t) 1 << (dig_per_u * logbase);
/* fall out to general code... */
@@ -318,9 +319,9 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
/* Allocate temporary digit space. We can't put digits directly in the user
area, since we generate more digits than requested. (We allocate
- BITS_PER_MP_LIMB extra bytes because of the digit block nature of the
+ GMP_LIMB_BITS extra bytes because of the digit block nature of the
conversion.) */
- tstr = (unsigned char *) TMP_ALLOC (n_digits + BITS_PER_MP_LIMB + 3);
+ tstr = (unsigned char *) TMP_ALLOC (n_digits + GMP_LIMB_BITS + 3);
for (digits_computed_so_far = 0; digits_computed_so_far < n_digits + 3;
digits_computed_so_far += dig_per_u)
@@ -337,6 +338,12 @@ mpf_get_str (char *digit_ptr, mp_exp_t *exp, int base, size_t n_digits, mpf_srcp
cy = mpn_mul_1 (rp, rp, rsize, big_base);
+ if (! POW2_P (GMP_NUMB_BITS))
+ {
+ if (digits_computed_so_far == 0 && cy == 0)
+ cy = mpn_mul_1 (rp, rp, rsize, big_base);
+ }
+
ASSERT_ALWAYS (! (digits_computed_so_far == 0 && cy == 0));
/* Convert N1 from BIG_BASE to a string of digits in BASE
diff --git a/mpf/get_ui.c b/mpf/get_ui.c
index df65a1f6c..c4a04706e 100644
--- a/mpf/get_ui.c
+++ b/mpf/get_ui.c
@@ -37,8 +37,8 @@ MA 02111-1307, USA.
unsigned long
mpf_get_ui (mpf_srcptr f)
{
- int size, abs_size;
- mp_exp_t exp;
+ mp_size_t size, abs_size;
+ mp_exp_t exp;
size = SIZ (f);
if (size == 0)