summaryrefslogtreecommitdiff
path: root/py/mpz.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-04-03 11:00:54 +0000
committerDamien George <damien.p.george@gmail.com>2014-04-03 11:00:54 +0000
commit8270e3853dc167d2d7946bb0de7a0f0bb2adde48 (patch)
treee261ee333b53fbe4560c94e37a531eaae2c0d60e /py/mpz.c
parenta58a7aefbd330261cc5c79c9fc9d5c6a12d2aeeb (diff)
py: More robust int conversion and overflow checking.
Diffstat (limited to 'py/mpz.c')
-rw-r--r--py/mpz.c31
1 files changed, 28 insertions, 3 deletions
diff --git a/py/mpz.c b/py/mpz.c
index 79d200d93..4a8941e29 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -1139,6 +1139,7 @@ mpz_t *mpz_mod(const mpz_t *lhs, const mpz_t *rhs) {
}
#endif
+// TODO check that this correctly handles overflow in all cases
machine_int_t mpz_as_int(const mpz_t *i) {
machine_int_t val = 0;
mpz_dig_t *d = i->dig + i->len;
@@ -1147,11 +1148,13 @@ machine_int_t mpz_as_int(const mpz_t *i) {
machine_int_t oldval = val;
val = (val << DIG_SIZE) | *d;
if (val < oldval) {
- // TODO need better handling of conversion overflow
+ // overflow, return +/- "infinity"
if (i->neg == 0) {
- return 0x7fffffff;
+ // +infinity
+ return ~WORD_MSBIT_HIGH;
} else {
- return 0x80000000;
+ // -infinity
+ return WORD_MSBIT_HIGH;
}
}
}
@@ -1163,6 +1166,28 @@ machine_int_t mpz_as_int(const mpz_t *i) {
return val;
}
+// TODO check that this correctly handles overflow in all cases
+bool mpz_as_int_checked(const mpz_t *i, machine_int_t *value) {
+ machine_int_t val = 0;
+ mpz_dig_t *d = i->dig + i->len;
+
+ while (--d >= i->dig) {
+ machine_int_t oldval = val;
+ val = (val << DIG_SIZE) | *d;
+ if (val < oldval) {
+ // overflow
+ return false;
+ }
+ }
+
+ if (i->neg != 0) {
+ val = -val;
+ }
+
+ *value = val;
+ return true;
+}
+
#if MICROPY_ENABLE_FLOAT
mp_float_t mpz_as_float(const mpz_t *i) {
mp_float_t val = 0;