From 4e9fab94eba007b33f3976de91921e09f75dd3df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Fri, 6 May 2022 10:13:08 +0200 Subject: [PATCH] ecl_bignum: access the internal object with a macro ecl_bignum This provides a better data encapsulation and is more portable. Moreover it is consistent with how we handle other boxed values like ecl_doublefloat. --- src/c/alloc_2.d | 28 +++++----- src/c/big.d | 85 +++++++++++++++---------------- src/c/big_ll.d | 46 ++++++++--------- src/c/hash.d | 4 +- src/c/num_log.d | 14 ++--- src/c/num_rand.d | 2 +- src/c/number.d | 50 +++++++++--------- src/c/printer/integer_to_string.d | 6 +-- src/c/serialize.d | 12 ++--- src/h/number.h | 69 +++++++++++++------------ src/h/object.h | 8 ++- 11 files changed, 163 insertions(+), 161 deletions(-) diff --git a/src/c/alloc_2.d b/src/c/alloc_2.d index 511f526b9..7d1c300af 100644 --- a/src/c/alloc_2.d +++ b/src/c/alloc_2.d @@ -1329,9 +1329,9 @@ si_gc_stats(cl_object enable) } if (cl_core.bytes_consed == ECL_NIL) { cl_core.bytes_consed = ecl_alloc_object(t_bignum); - mpz_init2(cl_core.bytes_consed->big.big_num, 128); + mpz_init2(ecl_bignum(cl_core.bytes_consed), 128); cl_core.gc_counter = ecl_alloc_object(t_bignum); - mpz_init2(cl_core.gc_counter->big.big_num, 128); + mpz_init2(ecl_bignum(cl_core.gc_counter), 128); } update_bytes_consed(); @@ -1343,8 +1343,8 @@ si_gc_stats(cl_object enable) GC_print_stats = 0; cl_core.gc_stats = 0; } else if (enable == ecl_make_fixnum(0)) { - mpz_set_ui(cl_core.bytes_consed->big.big_num, 0); - mpz_set_ui(cl_core.gc_counter->big.big_num, 0); + mpz_set_ui(ecl_bignum(cl_core.bytes_consed), 0); + mpz_set_ui(ecl_bignum(cl_core.gc_counter), 0); } else { cl_core.gc_stats = 1; GC_print_stats = (enable == @':full'); @@ -1361,8 +1361,8 @@ gather_statistics() /* GC stats rely on bignums */ if (cl_core.gc_stats) { update_bytes_consed(); - mpz_add_ui(cl_core.gc_counter->big.big_num, - cl_core.gc_counter->big.big_num, + mpz_add_ui(ecl_bignum(cl_core.gc_counter), + ecl_bignum(cl_core.gc_counter), 1); } if (GC_old_start_callback) @@ -1372,8 +1372,8 @@ gather_statistics() static void update_bytes_consed () { #if GBC_BOEHM == 0 - mpz_add_ui(cl_core.bytes_consed->big.big_num, - cl_core.bytes_consed->big.big_num, + mpz_add_ui(ecl_bignum(cl_core.bytes_consed), + ecl_bignum(cl_core.bytes_consed), GC_get_bytes_since_gc()); #else /* This is not accurate and may wrap around. We try to detect this @@ -1384,15 +1384,15 @@ update_bytes_consed () { if (bytes > new_bytes) { cl_index wrapped; wrapped = ~((cl_index)0) - bytes; - mpz_add_ui(cl_core.bytes_consed->big.big_num, - cl_core.bytes_consed->big.big_num, + mpz_add_ui(ecl_bignum(cl_core.bytes_consed), + ecl_bignum(cl_core.bytes_consed), wrapped); - mpz_add_ui(cl_core.bytes_consed->big.big_num, - cl_core.bytes_consed->big.big_num, + mpz_add_ui(ecl_bignum(cl_core.bytes_consed), + ecl_bignum(cl_core.bytes_consed), new_bytes); } else { - mpz_add_ui(cl_core.bytes_consed->big.big_num, - cl_core.bytes_consed->big.big_num, + mpz_add_ui(ecl_bignum(cl_core.bytes_consed), + ecl_bignum(cl_core.bytes_consed), new_bytes - bytes); } bytes = new_bytes; diff --git a/src/c/big.d b/src/c/big.d index 273f62019..ebb71c937 100644 --- a/src/c/big.d +++ b/src/c/big.d @@ -233,7 +233,7 @@ _ecl_big_minus_big(cl_object a, cl_object b) cl_index size_b = ECL_BIGNUM_ABS_SIZE(b); cl_index size_z = (size_a < size_b)? (size_b + 1) : (size_a + 1); cl_object z = _ecl_alloc_compact_bignum(size_z); - mpz_sub(z->big.big_num, a->big.big_num, b->big.big_num); + mpz_sub(ecl_bignum(z), ecl_bignum(a), ecl_bignum(b)); return big_normalize(z); } @@ -244,7 +244,7 @@ _ecl_fix_minus_big(cl_fixnum a, cl_object b) cl_index size_z = size_b + limbs_per_fixnum; cl_object z = _ecl_alloc_compact_bignum(size_z); _ecl_big_set_fixnum(z, a); - mpz_sub(z->big.big_num, z->big.big_num, b->big.big_num); + mpz_sub(ecl_bignum(z), ecl_bignum(z), ecl_bignum(b)); return big_normalize(z); } @@ -253,7 +253,7 @@ _ecl_big_negate(cl_object a) { cl_index size_a = ECL_BIGNUM_ABS_SIZE(a); cl_object z = _ecl_alloc_compact_bignum(size_a); - mpz_neg(z->big.big_num, a->big.big_num); + mpz_neg(ecl_bignum(z), ecl_bignum(a)); return big_normalize(z); } @@ -266,7 +266,7 @@ _ecl_big_divided_by_big(cl_object a, cl_object b) cl_fixnum size_z = size_a - size_b + 1; if (size_z <= 0) size_z = 1; z = _ecl_alloc_compact_bignum(size_z); - mpz_tdiv_q(z->big.big_num,a->big.big_num,b->big.big_num); + mpz_tdiv_q(ecl_bignum(z), ecl_bignum(a), ecl_bignum(b)); return big_normalize(z); } @@ -274,7 +274,7 @@ cl_object _ecl_big_gcd(cl_object a, cl_object b) { cl_object z = _ecl_big_register0(); - mpz_gcd(z->big.big_num, a->big.big_num, b->big.big_num); + mpz_gcd(ecl_bignum(z), ecl_bignum(a), ecl_bignum(b)); return _ecl_big_register_normalize(z); } @@ -291,7 +291,7 @@ _ecl_big_ceiling(cl_object a, cl_object b, cl_object *pr) { cl_object q = _ecl_big_register0(); cl_object r = _ecl_big_register1(); - mpz_cdiv_qr(q->big.big_num, r->big.big_num, a->big.big_num, b->big.big_num); + mpz_cdiv_qr(ecl_bignum(q), ecl_bignum(r), ecl_bignum(a), ecl_bignum(b)); *pr = _ecl_big_register_normalize(r); return _ecl_big_register_normalize(q); } @@ -301,7 +301,7 @@ _ecl_big_floor(cl_object a, cl_object b, cl_object *pr) { cl_object q = _ecl_big_register0(); cl_object r = _ecl_big_register1(); - mpz_fdiv_qr(q->big.big_num, r->big.big_num, a->big.big_num, b->big.big_num); + mpz_fdiv_qr(ecl_bignum(q), ecl_bignum(r), ecl_bignum(a), ecl_bignum(b)); *pr = _ecl_big_register_normalize(r); return _ecl_big_register_normalize(q); } @@ -341,34 +341,34 @@ mp_realloc(void *ptr, size_t osize, size_t nsize) cl_object _ecl_big_set_fixnum(cl_object x, cl_fixnum f) { - mpz_set_si((x)->big.big_num,(f)); + mpz_set_si(ecl_bignum(x), (f)); return x; } cl_object _ecl_big_set_index(cl_object x, cl_index f) { - mpz_set_ui((x)->big.big_num,(f)); + mpz_set_ui(ecl_bignum(x), (f)); return x; } cl_fixnum _ecl_big_get_fixnum(cl_object x) { - return mpz_get_si((x)->big.big_num); + return mpz_get_si(ecl_bignum(x)); } cl_index _ecl_big_get_index(cl_object x) { - return mpz_get_ui((x)->big.big_num); + return mpz_get_ui(ecl_bignum(x)); } #elif GMP_LIMB_BITS >= ECL_FIXNUM_BITS cl_object _ecl_big_set_fixnum(cl_object x, cl_fixnum f) { if (f == 0) { - mpz_set_si(x->big.big_num, 0); + mpz_set_si(ecl_bignum(x), 0); } else if (f > 0) { ECL_BIGNUM_SIZE(x) = 1; ECL_BIGNUM_LIMBS(x)[0] = f; @@ -383,7 +383,7 @@ cl_object _ecl_big_set_index(cl_object x, cl_index f) { if (f == 0) { - mpz_set_si(x->big.big_num, 0); + mpz_set_si(ecl_bignum(x), 0); } else if (f > 0) { ECL_BIGNUM_SIZE(x) = 1; ECL_BIGNUM_LIMBS(x)[0] = f; @@ -414,25 +414,25 @@ _ecl_big_get_index(cl_object x) static inline bool _ecl_big_fits_in_fixnum(cl_object x) { - return mpz_fits_sint_p(x->big.big_num); + return mpz_fits_sint_p(ecl_bignum(x)); } static inline bool _ecl_big_fits_in_index(cl_object x) { - return mpz_fits_uint_p(x->big.big_num); + return mpz_fits_uint_p(ecl_bignum(x)); } #elif ECL_FIXNUM_BITS == ECL_LONG_BITS static inline bool _ecl_big_fits_in_fixnum(cl_object x) { - return mpz_fits_slong_p(x->big.big_num); + return mpz_fits_slong_p(ecl_bignum(x)); } static inline bool _ecl_big_fits_in_index(cl_object x) { - return mpz_fits_ulong_p(x->big.big_num); + return mpz_fits_ulong_p(ecl_bignum(x)); } #elif ECL_FIXNUM_BITS == ECL_LONG_LONG_BITS && GMP_LIMB_BITS >= ECL_FIXNUM_BITS static inline bool @@ -487,65 +487,65 @@ long double _ecl_big_to_long_double(cl_object o) { long double output = 0; - int i, l = mpz_size(o->big.big_num), exp = 0; + int i, l = mpz_size(ecl_bignum(o)), exp = 0; for (i = 0; i < l; i++) { - output += ldexpl(mpz_getlimbn(o->big.big_num, i), exp); + output += ldexpl(mpz_getlimbn(ecl_bignum(o), i), exp); exp += GMP_LIMB_BITS; } - return (mpz_sgn(o->big.big_num) < 0)? -output : output; + return (mpz_sgn(ecl_bignum(o)) < 0)? -output : output; } static void mpz_ior_op(cl_object out, cl_object i, cl_object j) { - mpz_ior(out->big.big_num, i->big.big_num, j->big.big_num); + mpz_ior(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); } static void mpz_xor_op(cl_object out, cl_object i, cl_object j) { - mpz_xor(out->big.big_num, i->big.big_num, j->big.big_num); + mpz_xor(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); } static void mpz_and_op(cl_object out, cl_object i, cl_object j) { - mpz_and(out->big.big_num, i->big.big_num, j->big.big_num); + mpz_and(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); } static void mpz_eqv_op(cl_object out, cl_object i, cl_object j) { - mpz_xor(out->big.big_num, i->big.big_num, j->big.big_num); - mpz_com(out->big.big_num, out->big.big_num); + mpz_xor(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); + mpz_com(ecl_bignum(out), ecl_bignum(out)); } static void mpz_nand_op(cl_object out, cl_object i, cl_object j) { - mpz_and(out->big.big_num, i->big.big_num, j->big.big_num); - mpz_com(out->big.big_num, out->big.big_num); + mpz_and(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); + mpz_com(ecl_bignum(out), ecl_bignum(out)); } static void mpz_nor_op(cl_object out, cl_object i, cl_object j) { - mpz_ior(out->big.big_num, i->big.big_num, j->big.big_num); - mpz_com(out->big.big_num, out->big.big_num); + mpz_ior(ecl_bignum(out), ecl_bignum(i), ecl_bignum(j)); + mpz_com(ecl_bignum(out), ecl_bignum(out)); } static void mpz_andc1_op(cl_object out, cl_object i, cl_object j) { - mpz_com(out->big.big_num, i->big.big_num); - mpz_and(out->big.big_num, out->big.big_num, j->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(i)); + mpz_and(ecl_bignum(out), ecl_bignum(out), ecl_bignum(j)); } static void mpz_orc1_op(cl_object out, cl_object i, cl_object j) { - mpz_com(out->big.big_num, i->big.big_num); - mpz_ior(out->big.big_num, out->big.big_num, j->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(i)); + mpz_ior(ecl_bignum(out), ecl_bignum(out), ecl_bignum(j)); } static void @@ -553,7 +553,7 @@ mpz_andc2_op(cl_object out, cl_object i, cl_object j) { /* (i & ~j) = ~((~i) | j) */ mpz_orc1_op(out, i, j); - mpz_com(out->big.big_num, out->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(out)); } static void @@ -561,44 +561,44 @@ mpz_orc2_op(cl_object out, cl_object i, cl_object j) { /* (i | ~j) = ~((~i) & j) */ mpz_andc1_op(out, i, j); - mpz_com(out->big.big_num, out->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(out)); } static void mpz_b_clr_op(cl_object out, cl_object i, cl_object j) { - mpz_set_si(out->big.big_num, 0); + mpz_set_si(ecl_bignum(out), 0); } static void mpz_b_set_op(cl_object o, cl_object i, cl_object j) { - mpz_set_si(o->big.big_num, -1); + mpz_set_si(ecl_bignum(o), -1); } static void mpz_b_1_op(cl_object out, cl_object i, cl_object j) { if (i != out) - mpz_set(out->big.big_num, i->big.big_num); + mpz_set(ecl_bignum(out), ecl_bignum(i)); } static void mpz_b_2_op(cl_object out, cl_object i, cl_object j) { - mpz_set(out->big.big_num, j->big.big_num); + mpz_set(ecl_bignum(out), ecl_bignum(j)); } static void mpz_b_c1_op(cl_object out, cl_object i, cl_object j) { - mpz_com(out->big.big_num, i->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(i)); } static void mpz_b_c2_op(cl_object out, cl_object i, cl_object j) { - mpz_com(out->big.big_num, j->big.big_num); + mpz_com(ecl_bignum(out), ecl_bignum(j)); } static _ecl_big_binary_op bignum_operations[16] = { @@ -623,8 +623,7 @@ _ecl_big_binary_op _ecl_big_boole_operator(int op) { unlikely_if((op < 0) || (op >= 16)) { - ecl_internal_error("_ecl_big_boole_operator passed " - "an invalid operator"); + ecl_internal_error("_ecl_big_boole_operator passed an invalid operator"); } return bignum_operations[op]; } diff --git a/src/c/big_ll.d b/src/c/big_ll.d index 14c882e88..9fa10093e 100644 --- a/src/c/big_ll.d +++ b/src/c/big_ll.d @@ -19,28 +19,28 @@ _ecl_big_register_free(cl_object x) {} cl_object _ecl_big_register_copy(cl_object old) { - cl_object new_big = ecl_alloc_object(t_bignum); - new_big->big.big_num = old->big.big_num; - return new_big; + cl_object new = ecl_alloc_object(t_bignum); + ecl_bignum(new) = ecl_bignum(old); + return new; } static cl_object big_normalize(cl_object x) { - if (x->big.big_num == 0ll) + if (ecl_bignum(x) == 0ll) return(ecl_make_fixnum(0)); - if (x->big.big_num <= MOST_POSITIVE_FIXNUM && x->big.big_num >= MOST_NEGATIVE_FIXNUM) - return(ecl_make_fixnum(x->big.big_num)); + if (ECL_NEGATIVE_FIXNUM <= ecl_bignum(x) && ecl_bignum(x) <= MOST_POSITIVE_FIXNUM) + return(ecl_make_fixnum(ecl_bignum(x))); return x; } cl_object _ecl_big_register_normalize(cl_object x) { - if (x->big.big_num == 0ll) + if (ecl_bignum(x) == 0ll) return(ecl_make_fixnum(0)); - if (x->big.big_num <= MOST_POSITIVE_FIXNUM && x->big.big_num >= MOST_NEGATIVE_FIXNUM) - return(ecl_make_fixnum(x->big.big_num)); + if (ECL_NEGATIVE_FIXNUM <= ecl_bignum(x) && ecl_bignum(x) <= MOST_POSITIVE_FIXNUM) + return(ecl_make_fixnum(ecl_bignum(x))); return _ecl_big_register_copy(x); } @@ -50,7 +50,7 @@ big_alloc(int size) volatile cl_object x = ecl_alloc_object(t_bignum); if (size <= 0) ecl_internal_error("negative or zero size for bignum in big_alloc"); - x->big.big_num = 0ll; + ecl_bignum(x) = 0ll; return x; } @@ -58,14 +58,14 @@ static cl_object _ecl_big_copy(cl_object x) { volatile cl_object y = ecl_alloc_object(t_bignum); - y->big.big_num = x->big.big_num; + ecl_bignum(y) = ecl_bignum(x); return y; } cl_object _ecl_big_gcd(cl_object x, cl_object y) { - big_num_t i = x->big.big_num, j = y->big.big_num; + big_num_t i = ecl_bignum(x), j = ecl_bignum(y); cl_object gcd = ecl_alloc_object(t_bignum); while ( 1 ) { big_num_t k; @@ -75,7 +75,7 @@ _ecl_big_gcd(cl_object x, cl_object y) j = k; } if ( j == 0 ) { - gcd->big.big_num = k; + ecl_bignum(gcd) = k; return gcd; } k = i % j; @@ -94,7 +94,7 @@ cl_object _ecl_big_times_big(cl_object x, cl_object y) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = x->big.big_num * y->big.big_num; + ecl_bignum(z) = ecl_bignum(x) * ecl_bignum(y); return z; } @@ -102,7 +102,7 @@ cl_object _ecl_big_times_fix(cl_object x, cl_fixnum y) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = x->big.big_num * y; + ecl_bignum(z) = ecl_bignum(x) * y; return big_normalize(z); } @@ -110,7 +110,7 @@ cl_object _ecl_big_plus_big(cl_object x, cl_object y) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = x->big.big_num + y->big.big_num; + ecl_bignum(z) = ecl_bignum(x) + ecl_bignum(y); return z; } @@ -118,7 +118,7 @@ cl_object _ecl_big_plus_fix(cl_object x, cl_fixnum y) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = x->big.big_num + y; + ecl_bignum(z) = ecl_bignum(x) + y; return big_normalize(z); } @@ -126,7 +126,7 @@ cl_object _ecl_fix_times_fix(cl_fixnum x, cl_fixnum y) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = x * y; + ecl_bignum(z) = x * y; return big_normalize(z); } @@ -135,8 +135,8 @@ _ecl_big_ceiling(cl_object a, cl_object b, cl_object *pr) { cl_object q = ecl_alloc_object(t_bignum); cl_object r = ecl_alloc_object(t_bignum); - q->big.num = x->big.num / y->big.big_num; - r->big.num = x->big.num % y->big.big_num; + ecl_bignum(q) = ecl_bignum(x) / ecl_bignum(y); + ecl_bignum(r) = ecl_bignum(x) % ecl_bignum(y); *pr = big_normalize(r); return big_normalize(q); } @@ -146,8 +146,8 @@ _ecl_big_floor(cl_object a, cl_object b, cl_object *pr) { cl_object q = ecl_alloc_object(t_bignum); cl_object r = ecl_alloc_object(t_bignum); - q->big.num = x->big.num / y->big.big_num; - r->big.num = x->big.num % y->big.big_num; + ecl_bignum(q) = ecl_bignum(x) / ecl_bignum(y); + ecl_bignum(r) = ecl_bignum(x) % ecl_bignum(y); *pr = big_normalize(r); return big_normalize(q); } @@ -156,7 +156,7 @@ cl_object _ecl_big_negate(cl_object x) { cl_object z = ecl_alloc_object(t_bignum); - z->big.big_num = -x->big.big_num; + ecl_bignum(z) = - ecl_bignum(x); return z; } diff --git a/src/c/hash.d b/src/c/hash.d index c7dbb8c2e..1017f3b77 100644 --- a/src/c/hash.d +++ b/src/c/hash.d @@ -242,8 +242,8 @@ _hash_equalp(int depth, cl_hashkey h, cl_object x) return hash_word(h, (cl_index)ecl_double_float(x)); case t_bignum: /* FIXME! We should be more precise here! */ - return hash_string(h, (unsigned char*)x->big.big_num->_mp_d, - abs(x->big.big_num->_mp_size) * + return hash_string(h, (unsigned char*)ecl_bignum(x)->_mp_d, + abs(ecl_bignum(x)->_mp_size) * sizeof(mp_limb_t)); case t_ratio: h = _hash_equalp(0, h, x->ratio.num); diff --git a/src/c/num_log.d b/src/c/num_log.d index ae801814d..1a10e420d 100644 --- a/src/c/num_log.d +++ b/src/c/num_log.d @@ -219,11 +219,11 @@ count_bits(cl_object x) } case t_bignum: if (_ecl_big_sign(x) >= 0) - count = mpz_popcount(x->big.big_num); + count = mpz_popcount(ecl_bignum(x)); else { cl_object z = _ecl_big_register0(); - mpz_com(z->big.big_num, x->big.big_num); - count = mpz_popcount(z->big.big_num); + mpz_com(ecl_bignum(z), ecl_bignum(x)); + count = mpz_popcount(ecl_bignum(z)); _ecl_big_register_free(z); } break; @@ -262,13 +262,13 @@ ecl_ash(cl_object x, cl_fixnum w) } return ecl_make_fixnum(y); } - mpz_div_2exp(y->big.big_num, x->big.big_num, bits); + mpz_div_2exp(ecl_bignum(y), ecl_bignum(x), bits); } else { if (ECL_FIXNUMP(x)) { _ecl_big_set_fixnum(y, ecl_fixnum(x)); x = y; } - mpz_mul_2exp(y->big.big_num, x->big.big_num, (unsigned long)w); + mpz_mul_2exp(ecl_bignum(y), ecl_bignum(x), (unsigned long)w); } return _ecl_big_register_normalize(y); } @@ -388,7 +388,7 @@ cl_logbitp(cl_object p, cl_object x) i = ((y >> n) & 1); } } else { - i = mpz_tstbit(x->big.big_num, n); + i = mpz_tstbit(ecl_bignum(x), n); } } else { assert_type_non_negative_integer(p); @@ -458,7 +458,7 @@ ecl_integer_length(cl_object x) case t_bignum: if (_ecl_big_sign(x) < 0) x = cl_lognot(x); - count = mpz_sizeinbase(x->big.big_num, 2); + count = mpz_sizeinbase(ecl_bignum(x), 2); break; default: FEwrong_type_only_arg(@[integer-length], x, @[integer]); diff --git a/src/c/num_rand.d b/src/c/num_rand.d index e474e5c9c..5da8db4cb 100644 --- a/src/c/num_rand.d +++ b/src/c/num_rand.d @@ -232,7 +232,7 @@ random_integer(cl_object limit, cl_object state) if (bit_length <= ECL_FIXNUM_BITS) bit_length = ECL_FIXNUM_BITS; buffer = ecl_ash(ecl_make_fixnum(1), bit_length); - for (bit_length = mpz_size(buffer->big.big_num); bit_length; ) { + for (bit_length = mpz_size(ecl_bignum(buffer)); bit_length; ) { ECL_BIGNUM_LIMBS(buffer)[--bit_length] = generate_limb(state); } diff --git a/src/c/number.d b/src/c/number.d index c6511af69..8395f3a69 100644 --- a/src/c/number.d +++ b/src/c/number.d @@ -236,15 +236,15 @@ ecl_to_uint64_t(cl_object x) { return (ecl_uint64_t)ecl_fixnum(x); } else if (!ECL_BIGNUMP(x)) { (void)0; - } else if (mpz_fits_ulong_p(x->big.big_num)) { - return (ecl_uint64_t)mpz_get_ui(x->big.big_num); + } else if (mpz_fits_ulong_p(ecl_bignum(x))) { + return (ecl_uint64_t)mpz_get_ui(ecl_bignum(x)); } else { cl_object copy = _ecl_big_register0(); - mpz_fdiv_q_2exp(copy->big.big_num, x->big.big_num, 32); - if (mpz_fits_ulong_p(copy->big.big_num)) { + mpz_fdiv_q_2exp(ecl_bignum(copy), ecl_bignum(x), 32); + if (mpz_fits_ulong_p(ecl_bignum(copy))) { ecl_uint64_t output; - output = (ecl_uint64_t)mpz_get_ui(copy->big.big_num); - output = (output << 32) + (ecl_uint64_t)mpz_get_ui(x->big.big_num); + output = (ecl_uint64_t)mpz_get_ui(ecl_bignum(copy)); + output = (output << 32) + (ecl_uint64_t)mpz_get_ui(ecl_bignum(x)); _ecl_big_register_free(copy); return output; } @@ -262,16 +262,16 @@ ecl_to_int64_t(cl_object x) { return (ecl_int64_t)ecl_fixnum(x); } else if (!ECL_BIGNUMP(x)) { (void)0; - } else if (mpz_fits_slong_p(x->big.big_num)) { - return (ecl_int64_t)mpz_get_si(x->big.big_num); + } else if (mpz_fits_slong_p(ecl_bignum(x))) { + return (ecl_int64_t)mpz_get_si(ecl_bignum(x)); } else { cl_object copy = _ecl_big_register0(); - mpz_fdiv_q_2exp(copy->big.big_num, x->big.big_num, 32); - if (mpz_fits_slong_p(copy->big.big_num)) { + mpz_fdiv_q_2exp(ecl_bignum(copy), ecl_bignum(x), 32); + if (mpz_fits_slong_p(ecl_bignum(copy))) { ecl_int64_t output; - output = (ecl_int64_t)mpz_get_si(copy->big.big_num); - mpz_fdiv_r_2exp(copy->big.big_num, x->big.big_num, 32); - output = (output << 32) + mpz_get_ui(copy->big.big_num); + output = (ecl_int64_t)mpz_get_si(ecl_bignum(copy)); + mpz_fdiv_r_2exp(ecl_bignum(copy), ecl_bignum(x), 32); + output = (output << 32) + mpz_get_ui(ecl_bignum(copy)); _ecl_big_register_free(copy); return output; } @@ -354,19 +354,19 @@ ecl_to_ulong_long(cl_object x) { return (ecl_ulong_long_t)ecl_fixnum(x); } else if (!ECL_BIGNUMP(x)) { (void)0; - } else if (mpz_fits_ulong_p(x->big.big_num)) { - return (ecl_ulong_long_t)mpz_get_ui(x->big.big_num); + } else if (mpz_fits_ulong_p(ecl_bignum(x))) { + return (ecl_ulong_long_t)mpz_get_ui(ecl_bignum(x)); } else { cl_object copy = _ecl_big_register0(); int i = ECL_LONG_LONG_BITS - ECL_FIXNUM_BITS; - mpz_fdiv_q_2exp(copy->bit.big_num, x->big.big_num, i); - if (mpz_fits_ulong_p(copy->big.big_num)) { + mpz_fdiv_q_2exp(copy->bit.big_num, ecl_bignum(x), i); + if (mpz_fits_ulong_p(ecl_bignum(copy))) { ecl_ulong_long_t output; - output = mpz_get_ui(copy->big.big_num); + output = mpz_get_ui(ecl_bignum(copy)); for (i -= ECL_FIXNUM_BITS; i; i-= ECL_FIXNUM_BITS) { output = (output << ECL_FIXNUM_BITS); - output += mpz_get_ui(x->big.big_num); + output += mpz_get_ui(ecl_bignum(x)); } _ecl_big_register_free(copy); return output; @@ -387,18 +387,18 @@ ecl_to_long_long(cl_object x) return (ecl_long_long_t)ecl_fixnum(x); } else if (!ECL_BIGNUMP(x)) { (void)0; - } else if (mpz_fits_slong_p(x->big.big_num)) { - return (ecl_long_long_t)mpz_get_si(x->big.big_num); + } else if (mpz_fits_slong_p(ecl_bignum(x))) { + return (ecl_long_long_t)mpz_get_si(ecl_bignum(x)); } else { cl_object copy = _ecl_big_register0(); int i = ECL_LONG_LONG_BITS - ECL_FIXNUM_BITS; - mpz_fdiv_q_2exp(copy->bit.big_num, x->big.big_num, i); - if (mpz_fits_ulong_p(copy->big.big_num)) { + mpz_fdiv_q_2exp(copy->bit.big_num, ecl_bignum(x), i); + if (mpz_fits_ulong_p(ecl_bignum(copy))) { ecl_long_long_t output; - output = mpz_get_si(copy->big.big_num); + output = mpz_get_si(ecl_bignum(copy)); for (i -= ECL_FIXNUM_BITS; i; i-= ECL_FIXNUM_BITS) { output = (output << ECL_FIXNUM_BITS); - output += mpz_get_ui(x->big.big_num); + output += mpz_get_ui(ecl_bignum(x)); } _ecl_big_register_free(copy); return output; diff --git a/src/c/printer/integer_to_string.d b/src/c/printer/integer_to_string.d index d3e04d3b8..7b1ab7d3d 100644 --- a/src/c/printer/integer_to_string.d +++ b/src/c/printer/integer_to_string.d @@ -27,17 +27,17 @@ bignum_to_string(cl_object buffer, cl_object x, cl_object base) cl_list(3, @'integer', ecl_make_fixnum(2), ecl_make_fixnum(36))); } - str_size = mpz_sizeinbase(x->big.big_num, b); + str_size = mpz_sizeinbase(ecl_bignum(x), b); buffer = _ecl_ensure_buffer(buffer, str_size+1); if (str_size <= 62) { /* With the leading sign and the trailing null character, * only 62 digits fit in this buffer. */ char txt[64]; - mpz_get_str(txt, -b, x->big.big_num); + mpz_get_str(txt, -b, ecl_bignum(x)); _ecl_string_push_c_string(buffer, txt); } else { char *txt = ecl_alloc_atomic(str_size + 2); - mpz_get_str(txt, -b, x->big.big_num); + mpz_get_str(txt, -b, ecl_bignum(x)); _ecl_string_push_c_string(buffer, txt); ecl_dealloc(txt); } diff --git a/src/c/serialize.d b/src/c/serialize.d index ec20f7a12..f7aaa0ab0 100644 --- a/src/c/serialize.d +++ b/src/c/serialize.d @@ -241,13 +241,13 @@ serialize_one(pool_t pool, cl_object what) case t_longfloat: break; case t_bignum: { - int8_t sign = mpz_sgn(buffer->big.big_num); + int8_t sign = mpz_sgn(ecl_bignum(buffer)); serialize_bits(pool, &sign, 1); - cl_index bytes = (mpz_sizeinbase(buffer->big.big_num, 2) + 7) / 8; + cl_index bytes = (mpz_sizeinbase(ecl_bignum(buffer), 2) + 7) / 8; serialize_bits(pool, &bytes, sizeof(cl_index)); cl_index index = alloc(pool, bytes); cl_index bytes_written; - mpz_export(pool->data->vector.self.b8 + index, &bytes_written, 1, 1, 1, 0, buffer->big.big_num); + mpz_export(pool->data->vector.self.b8 + index, &bytes_written, 1, 1, 1, 0, ecl_bignum(buffer)); break; } case t_ratio: { @@ -459,10 +459,10 @@ reconstruct_one(uint8_t *data, cl_object *output) data += ROUND_TO_WORD(1); cl_index bytes = (cl_index) *data; data += ROUND_TO_WORD(sizeof(cl_index)); - mpz_init((*output)->big.big_num); - mpz_import((*output)->big.big_num, bytes, 1, 1, 1, 0, data); + mpz_init(ecl_bignum(*output)); + mpz_import(ecl_bignum(*output), bytes, 1, 1, 1, 0, data); if (sign == -1) { - mpz_neg((*output)->big.big_num, (*output)->big.big_num); + mpz_neg(ecl_bignum(*output), ecl_bignum(*output)); } data += ROUND_TO_WORD(bytes); break; diff --git a/src/h/number.h b/src/h/number.h index e2fe43a2f..3d41b3a42 100644 --- a/src/h/number.h +++ b/src/h/number.h @@ -27,11 +27,16 @@ extern "C" { #define ECL_WITH_TEMP_BIGNUM(name,n) \ mp_limb_t name##data[n]; \ volatile struct ecl_bignum name##aux; \ - const cl_object name = (name##aux.big_num->_mp_alloc = n, \ - name##aux.big_num->_mp_size = 0, \ - name##aux.big_num->_mp_d = name##data, \ + const cl_object name = (name##aux.value->_mp_alloc = n, \ + name##aux.value->_mp_size = 0, \ + name##aux.value->_mp_d = name##data, \ (cl_object)(&name##aux)) +#define ECL_BIGNUM_DIM(x) (ecl_bignum(x)->_mp_alloc) /* number of allocated limbs */ +#define ECL_BIGNUM_SIZE(x) (ecl_bignum(x)->_mp_size) /* number of limbs in use times sign of the bignum */ +#define ECL_BIGNUM_LIMBS(x) (ecl_bignum(x)->_mp_d) /* pointer to array of allocated limbs */ + +/* Bignum internal protocol */ 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); @@ -41,36 +46,36 @@ typedef void (*_ecl_big_binary_op)(cl_object out, cl_object o1, cl_object o2); extern ECL_API _ecl_big_binary_op _ecl_big_boole_operator(int op); #if ECL_LONG_BITS >= ECL_FIXNUM_BITS -#define _ecl_big_set_fixnum(x, f) mpz_set_si((x)->big.big_num,(f)) -#define _ecl_big_set_index(x, f) mpz_set_ui((x)->big.big_num,(f)) +#define _ecl_big_set_fixnum(x, f) mpz_set_si(ecl_bignum(x),(f)) +#define _ecl_big_set_index(x, f) mpz_set_ui(ecl_bignum(x),(f)) #endif -#define _ecl_big_init2(x,size) mpz_init2((x)->big.big_num,(size)*GMP_LIMB_BITS) -#define _ecl_big_realloc2(x,size) mpz_realloc2((x)->big.big_num,(size)*GMP_LIMB_BITS) -#define _ecl_big_clear(x) mpz_clear((x)->big.big_num) -#define _ecl_big_set(x,y) mpz_set((x)->big.big_num,(y)->big.big_num) -#define _ecl_big_odd_p(x) ((mpz_get_ui(x->big.big_num) & 1) != 0) -#define _ecl_big_even_p(x) ((mpz_get_ui(x->big.big_num) & 1) == 0) -#define _ecl_big_zerop(x) (ECL_BIGNUM_SIZE(x) == 0) -#define _ecl_big_sign(x) ECL_BIGNUM_SIZE(x) -#define _ecl_big_compare(x, y) mpz_cmp(x->big.big_num, y->big.big_num) -#define _ecl_big_complement(z, x) mpz_neg((z)->big.big_num,(x)->big.big_num) -#define _ecl_big_add(z, x, y) mpz_add((z)->big.big_num,(x)->big.big_num,(y)->big.big_num) -#define _ecl_big_sub(z, x, y) mpz_sub((z)->big.big_num,(x)->big.big_num,(y)->big.big_num) -#define _ecl_big_mul(z, x, y) mpz_mul((z)->big.big_num,(x)->big.big_num,(y)->big.big_num) -#define _ecl_big_add_ui(z, x, i) mpz_add_ui(z->big.big_num, x->big.big_num, i) -#define _ecl_big_sub_ui(z, x, i) mpz_sub_ui(z->big.big_num, x->big.big_num, i) -#define _ecl_big_mul_ui(z, x, y) mpz_mul_ui((z)->big.big_num,(x)->big.big_num,(y)) -#define _ecl_big_div_ui(z, x, y) mpz_div_ui((z)->big.big_num,(x)->big.big_num,(y)) -#define _ecl_big_mul_si(z, x, y) mpz_mul_si((z)->big.big_num,(x)->big.big_num,(y)) -#define _ecl_big_set_ui(x, i) mpz_set_ui(x->big.big_num, (unsigned long int)i) -#define _ecl_big_set_si(x, i) mpz_set_si(x->big.big_num, (long int)i) -#define _ecl_big_to_double(x) mpz_get_d(x->big.big_num) -#define _ecl_big_to_long(x) mpz_get_si(x->big.big_num) -#define _ecl_big_to_ulong(x) mpz_get_ui(x->big.big_num) -#define _ecl_big_cmp_si(x,y) mpz_cmp_si((x)->big.big_num,(y)) -#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)) +#define _ecl_big_init2(x,size) mpz_init2(ecl_bignum(x),(size)*GMP_LIMB_BITS) +#define _ecl_big_realloc2(x,size) mpz_realloc2(ecl_bignum(x),(size)*GMP_LIMB_BITS) +#define _ecl_big_clear(x) mpz_clear(ecl_bignum(x)) +#define _ecl_big_set(x,y) mpz_set(ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_odd_p(x) ((mpz_get_ui(ecl_bignum(x)) & 1) != 0) +#define _ecl_big_even_p(x) ((mpz_get_ui(ecl_bignum(x)) & 1) == 0) +#define _ecl_big_zerop(x) (ECL_BIGNUM_SIZE(x) == 0) +#define _ecl_big_sign(x) ECL_BIGNUM_SIZE(x) +#define _ecl_big_compare(x, y) mpz_cmp(ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_complement(z, x) mpz_neg(ecl_bignum(z),ecl_bignum(x)) +#define _ecl_big_add(z, x, y) mpz_add(ecl_bignum(z),ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_sub(z, x, y) mpz_sub(ecl_bignum(z),ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_mul(z, x, y) mpz_mul(ecl_bignum(z),ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_add_ui(z, x, i) mpz_add_ui(ecl_bignum(z),ecl_bignum(x),(i)) +#define _ecl_big_sub_ui(z, x, i) mpz_sub_ui(ecl_bignum(z),ecl_bignum(x),(i)) +#define _ecl_big_mul_ui(z, x, y) mpz_mul_ui(ecl_bignum(z),ecl_bignum(x),(y)) +#define _ecl_big_div_ui(z, x, y) mpz_div_ui(ecl_bignum(z),ecl_bignum(x),(y)) +#define _ecl_big_mul_si(z, x, y) mpz_mul_si(ecl_bignum(z),ecl_bignum(x),(y)) +#define _ecl_big_set_ui(x, i) mpz_set_ui(ecl_bignum(x),(unsigned long int)i) +#define _ecl_big_set_si(x, i) mpz_set_si(ecl_bignum(x),(long int)i) +#define _ecl_big_to_double(x) mpz_get_d(ecl_bignum(x)) +#define _ecl_big_to_long(x) mpz_get_si(ecl_bignum(x)) +#define _ecl_big_to_ulong(x) mpz_get_ui(ecl_bignum(x)) +#define _ecl_big_cmp_si(x,y) mpz_cmp_si(ecl_bignum(x),(y)) +#define _ecl_big_tdiv_q(q, x, y) mpz_tdiv_q(ecl_bignum(q),ecl_bignum(x),ecl_bignum(y)) +#define _ecl_big_tdiv_q_ui(q, x, y) mpz_tdiv_q_ui(ecl_bignum(q),ecl_bignum(x), (y)) +#define _ecl_big_set_d(x, d) mpz_set_d(ecl_bignum(x),(d)) #if ECL_CAN_INLINE diff --git a/src/h/object.h b/src/h/object.h index 69c26660f..578c61e9b 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -216,14 +216,12 @@ struct ecl_long_float { }; #define ecl_long_float(o) ((o)->longfloat.value) +typedef mpz_t big_num_t; struct ecl_bignum { _ECL_HDR; - mpz_t big_num; + big_num_t value; }; - -#define ECL_BIGNUM_DIM(x) ((x)->big.big_num->_mp_alloc) /* number of allocated limbs */ -#define ECL_BIGNUM_SIZE(x) ((x)->big.big_num->_mp_size) /* number of limbs in use times sign of the bignum */ -#define ECL_BIGNUM_LIMBS(x) ((x)->big.big_num->_mp_d) /* pointer to array of allocated limbs */ +#define ecl_bignum(o) ((o)->big.value) struct ecl_ratio { _ECL_HDR;