diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-01-25 06:33:29 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-01-25 06:33:29 -0800 |
commit | 4c71a77f2c39a8158c80b40af1a5cc2358251a00 (patch) | |
tree | f3c49877aed2a6898b89662f06a17cbc06c080ca /mpi | |
parent | 8195fbed4a8067362656d38e56fec3c4eb3deef1 (diff) | |
download | txr-4c71a77f2c39a8158c80b40af1a5cc2358251a00.tar.gz txr-4c71a77f2c39a8158c80b40af1a5cc2358251a00.tar.bz2 txr-4c71a77f2c39a8158c80b40af1a5cc2358251a00.zip |
Provide faster bignum-in-fixed-integer range tests in MPI.
* mpi/mpi.c (mp_in_range, mp_in_intptr_range,
mp_in_uintptr_range): New functions.
* mpi/mpi.h (mp_in_range, mp_in_intptr_range,
mp_in_uintptr_range): Declared.
* arith.c (NUM_MAX_MP, INT_PTR_MAX_MP, UINT_PTR_MAX_MP,
INT_PTR_MAX_SUCC_MP): Static variables removed. Note that
INT_PTR_MAX_MP was not used at all!
(normalize): Use mp_in_range instead magnitude comparison to
NUM_MAX_MP.
(in_int_ptr_range, in_uint_ptr_range): Static functions removed.
(c_unum): Use mp_in_uintptr_range instead of
in_uint_ptr_range.
(arith_init): Remove initializations of removed variables.
(arith_free_all): Remove cleanup of removed variables, leaving
function empty.
* lib.c (c_num): Use mp_in_intptr_range instead of
in_int_ptr_range.
Diffstat (limited to 'mpi')
-rw-r--r-- | mpi/mpi.c | 31 | ||||
-rw-r--r-- | mpi/mpi.h | 3 |
2 files changed, 34 insertions, 0 deletions
@@ -469,6 +469,37 @@ mp_err mp_get_intptr(mp_int *mp, int_ptr_t *z) return MP_OKAY; } +int mp_in_range(mp_int *mp, uint_ptr_t lim, int unsig) +{ + const int ptrnd = (SIZEOF_PTR + MP_DIGIT_BIT - 1) / MP_DIGIT_BIT; + mp_size nd = USED(mp); + + if (unsig && ISNEG(mp)) + return 0; + + if (nd < ptrnd) + return 1; + + if (nd > ptrnd) + return 0; + + { + mp_digit top = DIGITS(mp)[ptrnd - 1]; + lim >>= ((ptrnd - 1) * MP_DIGIT_BIT); + return top <= lim; + } +} + +int mp_in_intptr_range(mp_int *mp) +{ + return mp_in_range(mp, INT_PTR_MAX, 0); +} + +int mp_in_uintptr_range(mp_int *mp) +{ + return mp_in_range(mp, UINT_PTR_MAX, 1); +} + #ifdef HAVE_DOUBLE_INTPTR_T mp_err mp_set_double_intptr(mp_int *mp, double_intptr_t z) { @@ -85,6 +85,9 @@ mp_err mp_set_uintptr(mp_int *mp, uint_ptr_t z); mp_err mp_set_intptr(mp_int *mp, int_ptr_t z); mp_err mp_get_uintptr(mp_int *mp, uint_ptr_t *z); mp_err mp_get_intptr(mp_int *mp, int_ptr_t *z); +int mp_in_range(mp_int *mp, uint_ptr_t lim, int unsig); +int mp_in_intptr_range(mp_int *mp); +int mp_in_uintptr_range(mp_int *mp); #ifdef HAVE_DOUBLE_INTPTR_T mp_err mp_set_double_intptr(mp_int *mp, double_intptr_t z); #endif |