-
-
Notifications
You must be signed in to change notification settings - Fork 11k
ENH: add timedelta modulus operator support (mm) #12120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1591,6 +1591,34 @@ TIMEDELTA_mm_d_divide(char **args, npy_intp *dimensions, npy_intp *steps, void * | |
} | ||
} | ||
|
||
NPY_NO_EXPORT void | ||
TIMEDELTA_mm_m_remainder(char **args, npy_intp *dimensions, npy_intp *steps, void *NPY_UNUSED(func)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function looks correct, thanks |
||
{ | ||
BINARY_LOOP { | ||
const npy_timedelta in1 = *(npy_timedelta *)ip1; | ||
const npy_timedelta in2 = *(npy_timedelta *)ip2; | ||
if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) { | ||
*((npy_timedelta *)op1) = NPY_DATETIME_NAT; | ||
} | ||
else { | ||
if (in2 == 0) { | ||
npy_set_floatstatus_divbyzero(); | ||
*((npy_timedelta *)op1) = 0; | ||
} | ||
else { | ||
/* handle mixed case the way Python does */ | ||
const npy_timedelta rem = in1 % in2; | ||
if ((in1 > 0) == (in2 > 0) || rem == 0) { | ||
*((npy_timedelta *)op1) = rem; | ||
} | ||
else { | ||
*((npy_timedelta *)op1) = rem + in2; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/* | ||
***************************************************************************** | ||
** FLOAT LOOPS ** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1173,6 +1173,57 @@ PyUFunc_DivisionTypeResolver(PyUFuncObject *ufunc, | |
} | ||
|
||
|
||
NPY_NO_EXPORT int | ||
PyUFunc_RemainderTypeResolver(PyUFuncObject *ufunc, | ||
NPY_CASTING casting, | ||
PyArrayObject **operands, | ||
PyObject *type_tup, | ||
PyArray_Descr **out_dtypes) | ||
{ | ||
int type_num1, type_num2; | ||
int i; | ||
|
||
type_num1 = PyArray_DESCR(operands[0])->type_num; | ||
type_num2 = PyArray_DESCR(operands[1])->type_num; | ||
|
||
/* Use the default when datetime and timedelta are not involved */ | ||
if (!PyTypeNum_ISDATETIME(type_num1) && !PyTypeNum_ISDATETIME(type_num2)) { | ||
return PyUFunc_DefaultTypeResolver(ufunc, casting, operands, | ||
type_tup, out_dtypes); | ||
} | ||
if (type_num1 == NPY_TIMEDELTA) { | ||
if (type_num2 == NPY_TIMEDELTA) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just write this:
That saves you from having to produce an error message for datetime, making all my above comments moot There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is all just copy-paste from other type resolvers. I was planning to leave room for implementing |
||
out_dtypes[0] = PyArray_PromoteTypes(PyArray_DESCR(operands[0]), | ||
PyArray_DESCR(operands[1])); | ||
if (out_dtypes[0] == NULL) { | ||
return -1; | ||
} | ||
out_dtypes[1] = out_dtypes[0]; | ||
Py_INCREF(out_dtypes[1]); | ||
out_dtypes[2] = out_dtypes[0]; | ||
Py_INCREF(out_dtypes[2]); | ||
} | ||
else { | ||
return raise_binary_type_reso_error(ufunc, operands); | ||
} | ||
} | ||
else { | ||
return raise_binary_type_reso_error(ufunc, operands); | ||
} | ||
|
||
/* Check against the casting rules */ | ||
if (PyUFunc_ValidateCasting(ufunc, casting, operands, out_dtypes) < 0) { | ||
for (i = 0; i < 3; ++i) { | ||
tylerjereddy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Py_DECREF(out_dtypes[i]); | ||
out_dtypes[i] = NULL; | ||
} | ||
return -1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
|
||
/* | ||
* True division should return float64 results when both inputs are integer | ||
* types. The PyUFunc_DefaultTypeResolver promotes 8 bit integers to float16 | ||
|
Uh oh!
There was an error while loading. Please reload this page.