summaryrefslogtreecommitdiffstats
path: root/arith.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-01-18 06:42:10 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-01-18 06:42:10 -0800
commit166927780f449e7b0c77345cad3150684d42d150 (patch)
tree917e60ffcc24e1970f1768369734dd2542a03e22 /arith.c
parent4a9d763799c3f0b3c17182b44e8497e174547120 (diff)
downloadtxr-166927780f449e7b0c77345cad3150684d42d150.tar.gz
txr-166927780f449e7b0c77345cad3150684d42d150.tar.bz2
txr-166927780f449e7b0c77345cad3150684d42d150.zip
New random-state-get-vec function.
* arith.c (UINT_PTR_MAX_MP): New static variable. (biggnum_from_uintptr): New function. (in_uint_ptr_range): New static function. (c_uint_ptr_num): New function. (arith_init): Initialize UINT_PTR_MAX_MP. * arith.h (bignum_from_uintptr, c_uint_ptr_num): Declared. * eval.c (eval_init): Register random-state-get-vec. * mpi/mpi.c (mp_set_uintptr, mp_get_uintptr): New functions. (mp_set_intptr, mp_get_intptr): Expressed in terms of mp_set_uintptr and mp_get_uintptr. * mpi/mpi.h (mp_set_uintptr, mp_get_uintptr): Declared. * rand.c (make_random_state): Handle vector seed. (random_state_get_vec): New function. * rand.h (random_state_get_vec): Declared. * txr.1: Documented new feature in make-random-state and new random-state-get-vec function.
Diffstat (limited to 'arith.c')
-rw-r--r--arith.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/arith.c b/arith.c
index 280d3b55..497aefa7 100644
--- a/arith.c
+++ b/arith.c
@@ -48,7 +48,7 @@
#define CNUM_BIT ((int) sizeof (cnum) * CHAR_BIT)
#define ABS(A) ((A) < 0 ? -(A) : (A))
-static mp_int NUM_MAX_MP, INT_PTR_MAX_MP;
+static mp_int NUM_MAX_MP, INT_PTR_MAX_MP, UINT_PTR_MAX_MP;
val make_bignum(void)
{
@@ -83,6 +83,13 @@ val bignum_from_long(long l)
#endif
}
+val bignum_from_uintptr(uint_ptr_t u)
+{
+ val n = make_bignum();
+ mp_set_uintptr(mp(n), u);
+ return n;
+}
+
#if HAVE_DOUBLE_INTPTR_T
static val bignum_dbl_ipt(double_intptr_t di)
@@ -110,6 +117,35 @@ val in_int_ptr_range(val bignum)
return (mp_cmp_mag(mp(bignum), &INT_PTR_MAX_MP) == MP_GT) ? nil : t;
}
+static val in_uint_ptr_range(val bignum)
+{
+ return (mp_cmp_z(mp(bignum)) == MP_LT ||
+ mp_cmp_mag(mp(bignum), &UINT_PTR_MAX_MP) == MP_GT) ? nil : t;
+}
+
+uint_ptr_t c_uint_ptr_num(val num)
+{
+ switch (type(num)) {
+ case CHR: case NUM:
+ {
+ cnum n = coerce(cnum, num) >> TAG_SHIFT;
+ if (n >= 0)
+ return n;
+ }
+ goto range;
+ case BGNUM:
+ if (in_uint_ptr_range(num)) {
+ uint_ptr_t out;
+ mp_get_uintptr(mp(num), &out);
+ return out;
+ }
+ range:
+ uw_throwf(error_s, lit("~s is out of uint_ptr_t range"), num, nao);
+ default:
+ type_mismatch(lit("~s is not an integer"), num, nao);
+ }
+}
+
int highest_bit(int_ptr_t n)
{
#if SIZEOF_PTR == 8
@@ -2275,6 +2311,8 @@ void arith_init(void)
mp_set_intptr(&NUM_MAX_MP, NUM_MAX);
mp_init(&INT_PTR_MAX_MP);
mp_set_intptr(&INT_PTR_MAX_MP, INT_PTR_MAX);
+ mp_init(&UINT_PTR_MAX_MP);
+ mp_set_uintptr(&UINT_PTR_MAX_MP, -1);
log2_init();
reg_varl(intern(lit("*flo-dig*"), user_package), num_fast(DBL_DIG));