support divmod for pos float

This commit is contained in:
blueloveTH 2025-09-28 19:31:47 +08:00
parent 2a9117f39d
commit 354e8fc03f
2 changed files with 38 additions and 1 deletions

View File

@ -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__);

View File

@ -114,3 +114,9 @@ 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, 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)