diff --git a/py/compile.c b/py/compile.c
index 4eab094230598c023e5f715af760d6c4a46fa35c..0a10b817682442b53c1fc9cb5a3532ae1ed0f83d 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -3,6 +3,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <math.h>
 
 #include "misc.h"
 #include "mpconfig.h"
@@ -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)) {
                         ; // pass
                     } 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));
                     } 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, arg0 / arg1);
+                        //pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, 
+                          //                          floor((mp_float_t)arg0 / arg1));
+                        pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, 
+                                                    python_floor_divide(arg0, arg1));
+			
                     } else {
                         // shouldn't happen
                         assert(0);
diff --git a/py/intdivmod.c b/py/intdivmod.c
new file mode 100644
index 0000000000000000000000000000000000000000..4cb363b5111a50a8c4be46cebba3d581ee0e9420
--- /dev/null
+++ b/py/intdivmod.c
@@ -0,0 +1,24 @@
+#include "mpconfig.h"
+
+machine_int_t python_modulo(machine_int_t dividend, machine_int_t divisor) {
+    machine_int_t lsign = (dividend >= 0) ? 1 :-1;
+    machine_int_t rsign = (divisor >= 0) ? 1 :-1;
+    dividend %= divisor;
+    if (lsign != rsign) {
+        dividend += divisor;
+    }
+  return dividend;
+}
+
+
+machine_int_t python_floor_divide(machine_int_t num, machine_int_t denom) {
+    machine_int_t lsign = num > 0 ? 1 : -1;
+    machine_int_t rsign = denom > 0 ? 1 : -1;
+    if (lsign == -1) {num *= -1;}
+    if (rsign == -1) {denom *= -1;}
+    if (lsign != rsign){
+        return - ( num + denom - 1) / denom;
+    } else {
+        return num / denom;
+    }
+}
diff --git a/py/intdivmod.h b/py/intdivmod.h
new file mode 100644
index 0000000000000000000000000000000000000000..7716bd21e9403fcddca76ee270b35e29ae042091
--- /dev/null
+++ b/py/intdivmod.h
@@ -0,0 +1,4 @@
+// Functions for integer modulo and floor division
+
+machine_int_t python_modulo(machine_int_t dividend, machine_int_t divisor);
+machine_int_t python_floor_divide(machine_int_t num, machine_int_t denom);
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 9c7727ba42ac85cff155cd8453d40bd520f0a73f..39ea7ca115d75ef1827d6ede7d0b519340a3fe23 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -1,5 +1,6 @@
 #include <stdint.h>
 #include <string.h>
+#include <stdio.h>
 
 #include "nlr.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) {
             case RT_BINARY_OP_INPLACE_FLOOR_DIVIDE: {
                 mpz_t rem; mpz_init_zero(&rem);
                 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);
                 break;
             }
@@ -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_divmod_inpl(&quo, &res->mpz, zlhs, zrhs);
                 mpz_deinit(&quo);
-		// Check signs and do Python style modulo
-		if (zlhs->neg != zrhs->neg) {
+		        // Check signs and do Python style modulo
+		        if (zlhs->neg != zrhs->neg) {
                     mpz_add_inpl(&res->mpz, &res->mpz, zrhs);
                 }
                 break;
diff --git a/py/runtime.c b/py/runtime.c
index 95c3a44159bafb83516794b4bc8a548217823ddf..94f319056654755f27050b347cca1e74e9d02d31 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
+#include <math.h>
 
 #include "nlr.h"
 #include "misc.h"
@@ -661,7 +662,11 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
                     break;
                 }
                 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
                 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);
diff --git a/tests/basics/floordivide.py b/tests/basics/floordivide.py
new file mode 100644
index 0000000000000000000000000000000000000000..930313d6c18644ad104cbead41b10bafab02351e
--- /dev/null
+++ b/tests/basics/floordivide.py
@@ -0,0 +1,29 @@
+# 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)    
diff --git a/tests/basics/modulo.py b/tests/basics/modulo.py
index ce7ed2578c761dee91ffdc6f5321482f1e0330eb..4d83db6ec89dcadb0bd2de267f55f7a950c8e208 100644
--- a/tests/basics/modulo.py
+++ b/tests/basics/modulo.py
@@ -1,5 +1,5 @@
 # check modulo matches python definition
-
+# This test compiler version
 print(123 % 7)
 print(-123 % 7)
 print(123 % -7)
@@ -7,7 +7,6 @@ print(-123 % -7)
 
 a = 321
 b = 19
-
 print(a % b)
 print(a % -b)
 print(-a % b)
@@ -21,3 +20,17 @@ 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)
+