From 354e8fc03fde194c93441510b71a4fe7896eed9f Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 28 Sep 2025 19:31:47 +0800 Subject: [PATCH] support divmod for pos float --- src/bindings/py_number.c | 31 +++++++++++++++++++++++++++++++ tests/02_float.py | 8 +++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/bindings/py_number.c b/src/bindings/py_number.c index 7e0bd5d6..1e8db693 100644 --- a/src/bindings/py_number.c +++ b/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. py_bindmagic(tp_int, __invert__, int__invert__); diff --git a/tests/02_float.py b/tests/02_float.py index e2b4821c..6d801938 100644 --- a/tests/02_float.py +++ b/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) \ No newline at end of file +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)