diff options
author | tege <tege@gmplib.org> | 2002-05-06 15:05:24 +0200 |
---|---|---|
committer | tege <tege@gmplib.org> | 2002-05-06 15:05:24 +0200 |
commit | 0e6c3fe79785bac780c57613a11a333ec6649453 (patch) | |
tree | 16e8ee3cca8e35f57f42e78aebd8ad08ad039997 | |
parent | 9a2cd598e3e9ea6f035ddc74e4c0bbc91542c459 (diff) | |
download | gmp-0e6c3fe79785bac780c57613a11a333ec6649453.tar.gz |
Nailify.
-rw-r--r-- | mpf/cmp_si.c | 44 | ||||
-rw-r--r-- | mpf/cmp_ui.c | 33 | ||||
-rw-r--r-- | mpf/div.c | 3 | ||||
-rw-r--r-- | mpf/div_2exp.c | 11 | ||||
-rw-r--r-- | mpf/div_ui.c | 15 | ||||
-rw-r--r-- | mpf/eq.c | 8 | ||||
-rw-r--r-- | mpf/get_d.c | 2 | ||||
-rw-r--r-- | mpf/get_d_2exp.c | 2 | ||||
-rw-r--r-- | mpf/get_si.c | 20 | ||||
-rw-r--r-- | mpf/get_str.c | 23 | ||||
-rw-r--r-- | mpf/get_ui.c | 4 |
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. */ @@ -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); @@ -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) |