Kaynağa Gözat

support divmod for pos float

blueloveTH 5 ay önce
ebeveyn
işleme
354e8fc03f
2 değiştirilmiş dosya ile 38 ekleme ve 1 silme
  1. 31 0
      src/bindings/py_number.c
  2. 7 1
      tests/02_float.py

+ 31 - 0
src/bindings/py_number.c

@@ -175,6 +175,20 @@ static bool int__mod__(int argc, py_Ref argv) {
     return true;
 }
 
+static bool float__floordiv__(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(2);
+    py_f64 lhs = py_tofloat(&argv[0]);
+    py_f64 rhs;
+    if(try_castfloat(&argv[1], &rhs)) {
+        if(rhs == 0.0) return ZeroDivisionError("float modulo by zero");
+        py_f64 r = fmod(lhs, rhs);
+        py_newfloat(py_retval(), trunc((lhs - r) / rhs));
+        return true;
+    }
+    py_newnotimplemented(py_retval());
+    return true;
+}
+
 static bool float__mod__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(2);
     py_f64 lhs = py_tofloat(&argv[0]);
@@ -201,6 +215,21 @@ static bool float__rmod__(int argc, py_Ref argv) {
     return true;
 }
 
+static bool float__divmod__(int argc, py_Ref argv) {
+    PY_CHECK_ARGC(2);
+    py_f64 lhs = py_tofloat(&argv[0]);
+    py_f64 rhs;
+    if(try_castfloat(&argv[1], &rhs)) {
+        if(rhs == 0.0) return ZeroDivisionError("float modulo by zero");
+        py_f64 r = fmod(lhs, rhs);
+        py_Ref p = py_newtuple(py_retval(), 2);
+        py_newfloat(&p[0], trunc((lhs - r) / rhs));
+        py_newfloat(&p[1], r);
+        return true;
+    }
+    return TypeError("divmod() expects int or float as divisor");
+}
+
 static bool int__divmod__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(2);
     PY_CHECK_ARG_TYPE(1, tp_int);
@@ -535,8 +564,10 @@ void pk_number__register() {
     py_bindmagic(tp_int, __divmod__, int__divmod__);
 
     // fmod
+    py_bindmagic(tp_float, __floordiv__, float__floordiv__);
     py_bindmagic(tp_float, __mod__, float__mod__);
     py_bindmagic(tp_float, __rmod__, float__rmod__);
+    py_bindmagic(tp_float, __divmod__, float__divmod__);
 
     // int.__invert__ & int.<BITWISE OP>
     py_bindmagic(tp_int, __invert__, int__invert__);

+ 7 - 1
tests/02_float.py

@@ -113,4 +113,10 @@ assert abs(0.0) == 0.0
 assert eq(10 % 4, 2)
 assert eq(10.5 % 4, 2.5)
 assert eq(10 % 4.5, 1.0)
-assert eq(10.5 % 4.5, 1.5)
+assert eq(10.5 % 4.5, 1.5)
+
+assert eq(10.5 // 4, 2.0)
+assert eq(10.5 // 4.5, 2.0)
+_0, _1 = divmod(10.5, 4)
+assert eq(_0, 2.0)
+assert eq(_1, 2.5)