summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-09-13 19:58:18 +0100
committerDamien George <damien.p.george@gmail.com>2014-09-13 19:58:18 +0100
commit83695596ed4fe3ad990b68cc5ff52c26caf2174d (patch)
treeed56b5df87a3c1837ee55808643fe2738c1124e1
parent8594ce228011e6264f59ade4ff8a7f2bfa90a649 (diff)
downloadmicropython-83695596ed4fe3ad990b68cc5ff52c26caf2174d.tar.gz
micropython-83695596ed4fe3ad990b68cc5ff52c26caf2174d.zip
py: Fix build error when float disabled; add test for divmod.
-rw-r--r--py/builtin.c6
-rw-r--r--tests/float/float_divmod.py25
-rw-r--r--tests/float/float_divmod_relaxed.py27
3 files changed, 56 insertions, 2 deletions
diff --git a/py/builtin.c b/py/builtin.c
index 5b70531aec..471e294ccb 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -247,14 +247,16 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
mp_int_t i1 = MP_OBJ_SMALL_INT_VALUE(o1_in);
mp_int_t i2 = MP_OBJ_SMALL_INT_VALUE(o2_in);
if (i2 == 0) {
+ #if MICROPY_PY_BUILTINS_FLOAT
zero_division_error:
+ #endif
nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero"));
}
mp_obj_t args[2];
args[0] = MP_OBJ_NEW_SMALL_INT(i1 / i2);
args[1] = MP_OBJ_NEW_SMALL_INT(i1 % i2);
return mp_obj_new_tuple(2, args);
-#if MICROPY_PY_BUILTINS_FLOAT
+ #if MICROPY_PY_BUILTINS_FLOAT
} else if (MP_OBJ_IS_TYPE(o1_in, &mp_type_float) || MP_OBJ_IS_TYPE(o2_in, &mp_type_float)) {
mp_float_t f1 = mp_obj_get_float(o1_in);
mp_float_t f2 = mp_obj_get_float(o2_in);
@@ -267,7 +269,7 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
mp_obj_new_float(f2),
};
return mp_obj_new_tuple(2, tuple);
-#endif
+ #endif
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
}
diff --git a/tests/float/float_divmod.py b/tests/float/float_divmod.py
new file mode 100644
index 0000000000..8e7cd435a5
--- /dev/null
+++ b/tests/float/float_divmod.py
@@ -0,0 +1,25 @@
+# test floating point floor divide and modulus
+# it has some tricky corner cases
+
+def test(x, y):
+ div, mod = divmod(x, y)
+ print('%.8f %.8f %.8f %.8f' % (x // y, x % y, div, mod))
+ print(div == x // y, mod == x % y, abs(div * y + mod - x) < 1e-15)
+
+test(1.23456, 0.7)
+test(-1.23456, 0.7)
+test(1.23456, -0.7)
+test(-1.23456, -0.7)
+
+a = 1.23456
+b = 0.7
+test(a, b)
+test(a, -b)
+test(-a, b)
+test(-a, -b)
+
+for i in range(25):
+ x = (i - 12.5) / 6
+ for j in range(25):
+ y = (j - 12.5) / 6
+ test(x, y)
diff --git a/tests/float/float_divmod_relaxed.py b/tests/float/float_divmod_relaxed.py
new file mode 100644
index 0000000000..7054d2ca67
--- /dev/null
+++ b/tests/float/float_divmod_relaxed.py
@@ -0,0 +1,27 @@
+# test floating point floor divide and modulus
+# it has some tricky corner cases
+
+# pyboard has 32-bit floating point and gives different (but still
+# correct) answers for certain combinations of divmod arguments.
+
+def test(x, y):
+ div, mod = divmod(x, y)
+ print(div == x // y, mod == x % y, abs(div * y + mod - x) < 1e-6)
+
+test(1.23456, 0.7)
+test(-1.23456, 0.7)
+test(1.23456, -0.7)
+test(-1.23456, -0.7)
+
+a = 1.23456
+b = 0.7
+test(a, b)
+test(a, -b)
+test(-a, b)
+test(-a, -b)
+
+for i in range(25):
+ x = (i - 12.5) / 6
+ for j in range(25):
+ y = (j - 12.5) / 6
+ test(x, y)