From cc83b4c01fc5ceb2f4e3bf1876f8854ee2047e75 Mon Sep 17 00:00:00 2001 From: Juan Jose Garcia Ripoll Date: Sun, 1 Jan 2012 19:32:32 +0100 Subject: [PATCH] fixint()/fixnnint() did not work when sizeof(long) < sizeof(fixnum) --- src/c/big.d | 45 +++++++++++++++++++++++++++++++++++++++++++++ src/c/number.d | 8 ++++---- src/h/external.h | 1 + src/h/number.h | 4 +++- 4 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/c/big.d b/src/c/big.d index 1cec472b6..7c84ceeb3 100644 --- a/src/c/big.d +++ b/src/c/big.d @@ -314,6 +314,24 @@ _ecl_big_set_index(cl_object x, cl_index f) mpz_set_ui((x)->big.big_num,(f)); return x; } + +cl_fixnum +_ecl_big_get_fixnum(cl_object x) +{ + return mpz_get_si((x)->big.big_num); +} + +cl_index +_ecl_big_get_index(cl_object x) +{ + return mpz_get_ui((x)->big.big_num); +} + +bool +_ecl_big_fits_in_index(cl_object x) +{ + return mpz_fits_ulong_p(x->big.big_num); +} #elif GMP_LIMB_BITS >= FIXNUM_BITS cl_object _ecl_big_set_fixnum(cl_object x, cl_fixnum f) @@ -342,6 +360,33 @@ _ecl_big_set_index(cl_object x, cl_index f) x->big.big_limbs[0] = -f; } } + +cl_fixnum +_ecl_big_get_fixnum(cl_object x) +{ + if (x->big.big_size == 0) { + return 0; + } else { + cl_fixnum n = x->big.big_limbs[0]; + return (x->big.big_size > 0) ? n : -n; + } +} + +cl_index +_ecl_big_get_index(cl_object x) +{ + if (x->big.big_size == 0) { + return 0; + } else { + return (cl_index)x->big.big_limbs[0]; + } +} + +bool +_ecl_big_fits_in_index(cl_object x) +{ + return (x->big.big_size & (~1)) == 0; +} #else # error "ECL cannot build with GMP when both long and mp_limb_t are smaller than cl_fixnum" #endif /* FIXNUM_BITS > GMP_LIMB_BITS, ECL_LONG_BITS */ diff --git a/src/c/number.d b/src/c/number.d index 8efa4ca6a..097e9f65b 100644 --- a/src/c/number.d +++ b/src/c/number.d @@ -49,8 +49,8 @@ fixint(cl_object x) if (FIXNUMP(x)) return fix(x); if (ECL_BIGNUMP(x)) { - if (mpz_fits_slong_p(x->big.big_num)) { - return mpz_get_si(x->big.big_num); + if (_ecl_big_fits_in_index(x)) { + return _ecl_big_get_fixnum(x); } } FEwrong_type_argument(@[fixnum], x); @@ -64,8 +64,8 @@ fixnnint(cl_object x) if (i >= 0) return i; } else if (ECL_BIGNUMP(x)) { - if (mpz_fits_ulong_p(x->big.big_num)) { - return mpz_get_ui(x->big.big_num); + if (_ecl_big_fits_in_index(x)) { + return _ecl_big_get_index(x); } } cl_error(9, @'simple-type-error', @':format-control', diff --git a/src/h/external.h b/src/h/external.h index c07c93561..18cf1b28b 100755 --- a/src/h/external.h +++ b/src/h/external.h @@ -1208,6 +1208,7 @@ extern ECL_API cl_object cl_logxor _ARGS((cl_narg narg, ...)); extern ECL_API cl_object cl_logand _ARGS((cl_narg narg, ...)); extern ECL_API cl_object cl_logeqv _ARGS((cl_narg narg, ...)); +extern ECL_API cl_fixnum ecl_logand_index(cl_object n, cl_index i); extern ECL_API cl_object ecl_boole(int op, cl_object x, cl_object y); extern ECL_API cl_object ecl_ash(cl_object x, cl_fixnum w); extern ECL_API int ecl_fixnum_bit_length(cl_fixnum l); diff --git a/src/h/number.h b/src/h/number.h index 3a8ff89ed..996e0aea8 100644 --- a/src/h/number.h +++ b/src/h/number.h @@ -27,6 +27,9 @@ extern ECL_API cl_object _ecl_big_set_fixnum(cl_object x, cl_fixnum f); extern ECL_API cl_object _ecl_big_set_index(cl_object x, cl_index f); +extern ECL_API cl_fixnum _ecl_big_get_fixnum(cl_object x); +extern ECL_API cl_index _ecl_big_get_index(cl_object x); +extern bool _ecl_big_fits_in_index(cl_object x); #ifdef ECL_LONG_FLOAT extern ECL_API long double _ecl_big_to_long_double(cl_object x); #endif @@ -62,5 +65,4 @@ extern ECL_API _ecl_big_binary_op _ecl_big_boole_operator(int op); #define _ecl_big_tdiv_q(q, x, y) mpz_tdiv_q((q)->big.big_num,(x)->big.big_num,(y)->big.big_num) #define _ecl_big_tdiv_q_ui(q, x, y) mpz_tdiv_q_ui((q)->big.big_num, (x)->big.big_num, (y)) #define _ecl_big_set_d(x, d) mpz_set_d((x)->big.big_num, (d)) - #endif /* ECL_NUMBER_H */