Commit 56402796 authored by Rachel Dowdall's avatar Rachel Dowdall
Browse files

Fixed floor division on mp ints and small ints. Added a floordivide test case.

parent cde8631f
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <math.h>
#include "misc.h" #include "misc.h"
#include "mpconfig.h" #include "mpconfig.h"
...@@ -141,12 +142,13 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) { ...@@ -141,12 +142,13 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_SLASH)) { } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_SLASH)) {
; // pass ; // pass
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) { } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) {
// XXX implement this properly as Python's % operator acts differently to C's
//pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 % arg1);
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, python_modulo(arg0, arg1)); pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, python_modulo(arg0, arg1));
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)) { } else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)) {
// XXX implement this properly as Python's // operator acts differently to C's //pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT,
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 / arg1); // floor((mp_float_t)arg0 / arg1));
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT,
python_floor_divide(arg0, arg1));
} else { } else {
// shouldn't happen // shouldn't happen
assert(0); assert(0);
......
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <stdio.h>
#include "nlr.h" #include "nlr.h"
#include "misc.h" #include "misc.h"
...@@ -97,6 +98,12 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { ...@@ -97,6 +98,12 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: { case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
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;
} }
...@@ -105,8 +112,8 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) { ...@@ -105,8 +112,8 @@ mp_obj_t int_binary_op(int 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 // Check signs and do Python style modulo
if (zlhs->neg != zrhs->neg) { if (zlhs->neg != zrhs->neg) {
mpz_add_inpl(&res->mpz, &res->mpz, zrhs); mpz_add_inpl(&res->mpz, &res->mpz, zrhs);
} }
break; break;
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <math.h>
#include "nlr.h" #include "nlr.h"
#include "misc.h" #include "misc.h"
...@@ -661,7 +662,11 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) { ...@@ -661,7 +662,11 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
break; break;
} }
case RT_BINARY_OP_FLOOR_DIVIDE: case RT_BINARY_OP_FLOOR_DIVIDE:
case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: lhs_val /= rhs_val; break; case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE:
{
lhs_val = python_floor_divide(lhs_val, rhs_val);
break;
}
#if MICROPY_ENABLE_FLOAT #if MICROPY_ENABLE_FLOAT
case RT_BINARY_OP_TRUE_DIVIDE: case RT_BINARY_OP_TRUE_DIVIDE:
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val);
......
# check modulo matches python definition
# This tests compiler version
print(123 // 7)
print(-123 // 7)
print(123 // -7)
print(-123 // -7)
a = 10000001
b = 10000000
print(a // b)
print(a // -b)
print(-a // b)
print(-a // -b)
if True:
a = 987654321987987987987987987987
b = 19
print(a // b)
print(a // -b)
print(-a // b)
print(-a // -b)
a = 10000000000000000000000000000000000000000000
b = 100
print(a // b)
print(a // -b)
print(-a // b)
print(-a // -b)
# check modulo matches python definition # check modulo matches python definition
# This test compiler version
print(123 % 7) print(123 % 7)
print(-123 % 7) print(-123 % 7)
print(123 % -7) print(123 % -7)
...@@ -7,7 +7,6 @@ print(-123 % -7) ...@@ -7,7 +7,6 @@ print(-123 % -7)
a = 321 a = 321
b = 19 b = 19
print(a % b) print(a % b)
print(a % -b) print(a % -b)
print(-a % b) print(-a % b)
...@@ -21,3 +20,17 @@ print(a % b) ...@@ -21,3 +20,17 @@ print(a % b)
print(a % -b) print(a % -b)
print(-a % b) print(-a % b)
print(-a % -b) print(-a % -b)
if False:
print(1.23456 % 0.7)
print(-1.23456 % 0.7)
print(1.23456 % -0.7)
print(-1.23456 % -0.7)
a = 1.23456
b = 0.7
print(a % b)
print(a % -b)
print(-a % b)
print(-a % -b)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment