-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
BUG: Fix strange behavior of infinite-step-size/underflow-case in arange #10263
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 6 commits
671a224
825c681
4af6233
2607ad7
123da27
e2cc3e6
d4d2758
2827c66
0b60753
41cd4e1
12d020c
c5f589d
abc1686
514c8ec
d68afb3
2740bc9
04a85b4
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 |
---|---|---|
|
@@ -2968,11 +2968,25 @@ PyArray_Arange(double start, double stop, double step, int type_num) | |
PyArray_ArrFuncs *funcs; | ||
PyObject *obj; | ||
int ret; | ||
double delta, tmp_len; | ||
NPY_BEGIN_THREADS_DEF; | ||
|
||
length = _arange_safe_ceil_to_intp((stop - start)/step); | ||
if (error_converting(length)) { | ||
return NULL; | ||
delta = stop - start; | ||
tmp_len = delta/step; | ||
|
||
if (tmp_len == 0.0 && delta != 0.0) { | ||
if (npy_signbit(tmp_len)) { | ||
length = -1.0; | ||
} | ||
else { | ||
length = 1.0; | ||
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. nit: should be |
||
} | ||
} | ||
else { | ||
length = _arange_safe_ceil_to_intp(tmp_len); | ||
if (error_converting(length)) { | ||
return NULL; | ||
} | ||
} | ||
|
||
if (length <= 0) { | ||
|
@@ -3035,7 +3049,8 @@ PyArray_Arange(double start, double stop, double step, int type_num) | |
static npy_intp | ||
_calc_length(PyObject *start, PyObject *stop, PyObject *step, PyObject **next, int cmplx) | ||
{ | ||
npy_intp len, tmp; | ||
npy_intp len, tmp, next_is_nonzero, val_is_zero; | ||
PyObject *zero = PyInt_FromLong(0); | ||
PyObject *val; | ||
double value; | ||
|
||
|
@@ -3049,12 +3064,19 @@ _calc_length(PyObject *start, PyObject *stop, PyObject *step, PyObject **next, i | |
} | ||
return -1; | ||
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. Need to |
||
} | ||
|
||
next_is_nonzero = PyObject_RichCompareBool(*next, zero, Py_NE); | ||
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. Could use 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. @eric-wieser IMO, |
||
val = PyNumber_TrueDivide(*next, step); | ||
Py_DECREF(*next); | ||
*next = NULL; | ||
|
||
if (!val) { | ||
return -1; | ||
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.
|
||
} | ||
|
||
val_is_zero = PyObject_RichCompareBool(val, zero, Py_EQ); | ||
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. Should be an 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. You need to check that this doesn't return -1, indicating an error occurred. Same above. |
||
Py_DECREF(zero); | ||
|
||
if (cmplx && PyComplex_Check(val)) { | ||
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. Trying to work out if this section needs a fix too, but I can't work out what this is even trying to do. 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. @eric-wieser Me too. I don't know why the complex case exists. This is none-sense as math. 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. See #10332. |
||
value = PyComplex_RealAsDouble(val); | ||
if (error_converting(value)) { | ||
|
@@ -3083,11 +3105,23 @@ _calc_length(PyObject *start, PyObject *stop, PyObject *step, PyObject **next, i | |
if (error_converting(value)) { | ||
return -1; | ||
} | ||
len = _arange_safe_ceil_to_intp(value); | ||
if (error_converting(len)) { | ||
return -1; | ||
|
||
if (val_is_zero && next_is_nonzero) { | ||
if (npy_signbit(value)) { | ||
len = -1.0; | ||
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. I think this should be |
||
} | ||
else { | ||
len = 1.0; | ||
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. Same here for int vs double |
||
} | ||
} | ||
else { | ||
len = _arange_safe_ceil_to_intp(value); | ||
if (error_converting(len)) { | ||
return -1; | ||
} | ||
} | ||
} | ||
|
||
if (len > 0) { | ||
*next = PyNumber_Add(start, step); | ||
if (!*next) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs a comment explaining why it is a special case
Isn't this only satisfied if
step
isinf
anyway?Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eric-wieser This also considers some underflow cases. eg. in master branch,