diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2015-04-22 19:53:47 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2015-04-22 19:53:47 -0700 |
commit | 686fd1ee9baa6e5700ceeecf801acf62696e8228 (patch) | |
tree | f908c967fd0a974574bfaa030f067b43a4fbc578 | |
parent | de299fde801e24b9ecd2fdd02e827c915304b9c3 (diff) | |
download | txr-686fd1ee9baa6e5700ceeecf801acf62696e8228.tar.gz txr-686fd1ee9baa6e5700ceeecf801acf62696e8228.tar.bz2 txr-686fd1ee9baa6e5700ceeecf801acf62696e8228.zip |
add-mp-set-intptr patch
* mpi/mpi.c (mp_set_intptr, mp_get_intptr): New functions.
* mpi/mpi.h (mp_set_intptr, mp_get_intptr): Declared.
-rw-r--r-- | mpi/mpi.c | 53 | ||||
-rw-r--r-- | mpi/mpi.h | 2 |
2 files changed, 55 insertions, 0 deletions
@@ -526,6 +526,59 @@ mp_err mp_set_int(mp_int *mp, long z) /* }}} */ +mp_err mp_set_intptr(mp_int *mp, int_ptr_t z) +{ + int_ptr_t v = z > 0 ? z : -z; + + if (sizeof z > sizeof (mp_digit)) { + int ix, shift; + const int nd = (sizeof v + sizeof (mp_digit) - 1) / sizeof (mp_digit); + + ARGCHK(mp != NULL, MP_BADARG); + + mp_zero(mp); + + if(z == 0) + return MP_OKAY; /* shortcut for zero */ + + s_mp_grow(mp, nd); + + USED(mp) = nd; + + for (ix = 0, shift = 0; ix < nd; ix++, shift += MP_DIGIT_BIT) + { + DIGIT(mp, ix) = (v >> shift) & MP_DIGIT_MAX; + } + } else { + mp_set(mp, v); + } + + if(z < 0) + SIGN(mp) = MP_NEG; + + return MP_OKAY; +} + +/* + * No checks here: assumes that the mp is in range! + */ +mp_err mp_get_intptr(mp_int *mp, int_ptr_t *z) +{ + int_ptr_t out = 0; + +#if MP_DIGIT_SIZE < SIZEOF_PTR + int ix; + int nd = USED(mp); + for (ix = 0; ix < nd; ix++, out <<= MP_DIGIT_BIT) + out = DIGIT(mp, ix); +#else + out = DIGIT(mp, 0); +#endif + + *z = (SIGN(mp) == MP_NEG) ? -out : out; + return MP_OKAY; +} + /*------------------------------------------------------------------------*/ /* {{{ Digit arithmetic */ @@ -94,6 +94,8 @@ void mp_clear_array(mp_int mp[], int count); void mp_zero(mp_int *mp); void mp_set(mp_int *mp, mp_digit d); mp_err mp_set_int(mp_int *mp, long z); +mp_err mp_set_intptr(mp_int *mp, int_ptr_t z); +mp_err mp_get_intptr(mp_int *mp, int_ptr_t *z); /*------------------------------------------------------------------------*/ /* Single digit arithmetic */ |