py/mpz: Do Python style division/modulo within bignum divmod routine.

This patch consolidates the Python logic for division/modulo to one place
within the bignum code.
This commit is contained in:
Damien George 2016-05-08 22:21:21 +01:00
parent dc3faea040
commit 65402ab1ec
3 changed files with 8 additions and 16 deletions

View File

@ -1509,8 +1509,14 @@ void mpz_divmod_inpl(mpz_t *dest_quo, mpz_t *dest_rem, const mpz_t *lhs, const m
//rhs->dig[rhs->len] = 0; //rhs->dig[rhs->len] = 0;
mpn_div(dest_rem->dig, &dest_rem->len, rhs->dig, rhs->len, dest_quo->dig, &dest_quo->len); mpn_div(dest_rem->dig, &dest_rem->len, rhs->dig, rhs->len, dest_quo->dig, &dest_quo->len);
// check signs and do Python style modulo
if (lhs->neg != rhs->neg) { if (lhs->neg != rhs->neg) {
dest_quo->neg = 1; dest_quo->neg = 1;
if (!mpz_is_zero(dest_rem)) {
mpz_t mpzone; mpz_init_from_int(&mpzone, -1);
mpz_add_inpl(dest_quo, dest_quo, &mpzone);
mpz_add_inpl(dest_rem, dest_rem, rhs);
}
} }
} }

View File

@ -239,12 +239,6 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
} }
mpz_t rem; mpz_init_zero(&rem); mpz_t rem; mpz_init_zero(&rem);
mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs); mpz_divmod_inpl(&res->mpz, &rem, zlhs, zrhs);
if (zlhs->neg != zrhs->neg) {
if (!mpz_is_zero(&rem)) {
mpz_t mpzone; mpz_init_from_int(&mpzone, -1);
mpz_add_inpl(&res->mpz, &res->mpz, &mpzone);
}
}
mpz_deinit(&rem); mpz_deinit(&rem);
break; break;
} }
@ -256,10 +250,6 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
mpz_t quo; mpz_init_zero(&quo); mpz_t quo; mpz_init_zero(&quo);
mpz_divmod_inpl(&quo, &res->mpz, zlhs, zrhs); mpz_divmod_inpl(&quo, &res->mpz, zlhs, zrhs);
mpz_deinit(&quo); mpz_deinit(&quo);
// Check signs and do Python style modulo
if (zlhs->neg != zrhs->neg) {
mpz_add_inpl(&res->mpz, &res->mpz, zrhs);
}
break; break;
} }
@ -303,10 +293,6 @@ mp_obj_t mp_obj_int_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
} }
mp_obj_int_t *quo = mp_obj_int_new_mpz(); mp_obj_int_t *quo = mp_obj_int_new_mpz();
mpz_divmod_inpl(&quo->mpz, &res->mpz, zlhs, zrhs); mpz_divmod_inpl(&quo->mpz, &res->mpz, zlhs, zrhs);
// Check signs and do Python style modulo
if (zlhs->neg != zrhs->neg) {
mpz_add_inpl(&res->mpz, &res->mpz, zrhs);
}
mp_obj_t tuple[2] = {MP_OBJ_FROM_PTR(quo), MP_OBJ_FROM_PTR(res)}; mp_obj_t tuple[2] = {MP_OBJ_FROM_PTR(quo), MP_OBJ_FROM_PTR(res)};
return mp_obj_new_tuple(2, tuple); return mp_obj_new_tuple(2, tuple);
} }

View File

@ -4,8 +4,8 @@ delta = 100000000000000000000000000000012345
for i in range(11): for i in range(11):
for j in range(11): for j in range(11):
x = delta * (i)# - 5) # TODO reinstate negative number test when % is working with sign correctly x = delta * (i - 5)
y = delta * (j)# - 5) # TODO reinstate negative number test when % is working with sign correctly y = delta * (j - 5)
if y != 0: if y != 0:
print(x % y) print(x % y)