You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
BUG: __floordiv__ gives NaN and invalid warning for 1//0 #14900
The __floordiv__ and __mod__ operators do not raise an exception for zero division with np.errstate(divide='raise'), instead replacing those instances with nan as if errstate is in the default state.
Ah, the issue is that npy_divmod in numpy/core/src/npymath/npy_math_internal.h.src has a special path for b == 0. This does not set the divide by 0 error flag (since it is hit before the divide happens). Maybe even reorganizing the code works (not sure what the compilers will do here).
I suppose the fmod causes an invalid warning to be set before, so I wonder if both should be set or only one?
Hey @seberg any place where we can learn the internals of this working or an overall architectural view of the system? and what is this extension *.h.src ?
The development workflow documents describe the .src extension. It is basically a very very simple templating language used in NumPy. It just repeats the code and fills in the @variable@. The overall architecture is sometimes a bit tricky, I would suggest grepping a bit, you will find this function is used in the umath folder which has everything to define ufuncs in it. Since there are some code generators, etc. please just ask if you are confused by something specific.
hi @seberg, i started looking more into this. is this still an issue. looks like fmod sets nan and probably causes invalid warning to be set. Tried to dig more into this and found : #7709 where it seems to indicate that this is intended behavior and not a bug. I also tried to dig into the code, to see where the invalid flag is set (either through NPY_FPE_INVALID or npy_set_floatstatus_invalid) for fmod but couldn't find it.
Seems there are actually two things here, since we unfortunately never fixed the thing that we should return Inf and not NaN.
@anirudh2290 there probably is no explicit setting, the flag probably gets set by the CPU during the modulo operation written in C (or similar). So the correct behaviour is arguably to return inf and set the "divide" warning.
What we need to figure out is which warning is correct. Python returns ZeroDivisionError also for 1 % 0, but that seems wrong when returning NaN (which is arguably correct). Now np.divmod() returns both, so which warning to pick? (I guess the one we currently have).
changed the title [-]errstate divide has no effect on __floordiv__ and __mod__[/-][+]BUG: `__floordiv__` gives NaN and invalid warning for `1//0`[/+]on May 5, 2020
thanks @seberg! Currently for np.divmod , it behaves differently for scalars and arrays. for scalar it returns (0, 0) and gives a divide by 0 warning. For arrays, it gives an array of nans (for both quotient and remainder) and gives an invalid warning. Is my understanding correct, that your preference is to return (inf, nan) and set the dividebyzero warning for both scalars and arrays ?
import numpy as np
x = np.ones((3, 3))
y = np.zeros((3, 3))
with np.errstate(all='warn'):
print(np.divmod(1, 0)) # this will warn divide by 0, and print (0, 0)
print(np.divmod(x, y)) # this will warn invalid and prints array of nans for both
I did not realize the 0, 0 result the issue you linked sounds like it should, but I am not sure, maybe I am missing something about divmod being special. 1//0 should return inf (unless you say that the floor(inf) gives NaN, I guess? So honestly, I am not quite sure immediately :)
I guess I was not completely accurate before. Float division for example np.divmod(1.0, 0.0) do print (inf, nan) print(nan, nan). But it has a different behavior for int or long division which is (0, 0).
Ah, thanks for making it more clear. Right for integers it is a bit more tricky, since the only other thing we could do is either always raise or return INT_MIN, which is also not ideal... I wonder if we have any prior art somewhere... What does C do?
Ah, thanks for making it more clear. Right for integers it is a bit more tricky, since the only other thing we could do is either always raise or return INT_MIN, which is also not ideal... I wonder if we have any prior art somewhere... What does C do?
This may be a stupid question but why can't we have the same behavior for int and float, that is set the div error and return inf and nan.
Ah, thanks for making it more clear. Right for integers it is a bit more tricky, since the only other thing we could do is either always raise or return INT_MIN, which is also not ideal... I wonder if we have any prior art somewhere... What does C do?
This may be a stupid question but why can't we have the same behavior for int and float, that is set the div error and return inf and nan.
okay, my bad. inf doesnt really make sense for int.
Digging into some history, I found this : #7510 , which raises ValueError, the discussion that happened on the issue seems to have converged to this comment : #7510 (comment) . I guess we decided to incrementally fix this and raise ValueError wherever we find such cases ?
Activity
Sriharsha-hatwar commentedon Nov 25, 2019
Very curious about working on this. but seems a little tricky, any inputs ? @eric-wieser ?
seberg commentedon Nov 25, 2019
Ah, the issue is that
npy_divmodinnumpy/core/src/npymath/npy_math_internal.h.srchas a special path forb == 0. This does not set the divide by 0 error flag (since it is hit before the divide happens). Maybe even reorganizing the code works (not sure what the compilers will do here).I suppose the
fmodcauses an invalid warning to be set before, so I wonder if both should be set or only one?Sriharsha-hatwar commentedon Nov 25, 2019
Hey @seberg any place where we can learn the internals of this working or an overall architectural view of the system? and what is this extension *.h.src ?
seberg commentedon Nov 25, 2019
The development workflow documents describe the
.srcextension. It is basically a very very simple templating language used in NumPy. It just repeats the code and fills in the@variable@. The overall architecture is sometimes a bit tricky, I would suggest grepping a bit, you will find this function is used in theumathfolder which has everything to define ufuncs in it. Since there are some code generators, etc. please just ask if you are confused by something specific.anirudh2290 commentedon May 4, 2020
hi @seberg, i started looking more into this. is this still an issue. looks like fmod sets nan and probably causes invalid warning to be set. Tried to dig more into this and found : #7709 where it seems to indicate that this is intended behavior and not a bug. I also tried to dig into the code, to see where the invalid flag is set (either through
NPY_FPE_INVALIDornpy_set_floatstatus_invalid) for fmod but couldn't find it.seberg commentedon May 4, 2020
Seems there are actually two things here, since we unfortunately never fixed the thing that we should return Inf and not NaN.
@anirudh2290 there probably is no explicit setting, the flag probably gets set by the CPU during the modulo operation written in C (or similar). So the correct behaviour is arguably to return inf and set the "divide" warning.
What we need to figure out is which warning is correct. Python returns ZeroDivisionError also for
1 % 0, but that seems wrong when returning NaN (which is arguably correct). Nownp.divmod()returns both, so which warning to pick? (I guess the one we currently have).[-]errstate divide has no effect on __floordiv__ and __mod__[/-][+]BUG: `__floordiv__` gives NaN and invalid warning for `1//0`[/+]anirudh2290 commentedon May 5, 2020
thanks @seberg! Currently for np.divmod , it behaves differently for scalars and arrays. for scalar it returns (0, 0) and gives a divide by 0 warning. For arrays, it gives an array of nans (for both quotient and remainder) and gives an invalid warning. Is my understanding correct, that your preference is to return (inf, nan) and set the dividebyzero warning for both scalars and arrays ?
seberg commentedon May 5, 2020
I did not realize the
0, 0result the issue you linked sounds like it should, but I am not sure, maybe I am missing something about divmod being special.1//0should returninf(unless you say that thefloor(inf)gives NaN, I guess? So honestly, I am not quite sure immediately :)anirudh2290 commentedon May 5, 2020
I guess I was not completely accurate before. Float division for example np.divmod(1.0, 0.0) do
print (inf, nan)print(nan, nan). But it has a different behavior for int or long division which is (0, 0).EDIT: I meant print (nan, nan).
seberg commentedon May 5, 2020
Ah, thanks for making it more clear. Right for integers it is a bit more tricky, since the only other thing we could do is either always raise or return
INT_MIN, which is also not ideal... I wonder if we have any prior art somewhere... What does C do?anirudh2290 commentedon May 5, 2020
for c 1/0 is undefined behavior, on my compiler it gives floating point error core dumped. 1.0/0.0 returns inf, conforming to IEEE754 standard.
anirudh2290 commentedon May 5, 2020
This may be a stupid question but why can't we have the same behavior for int and float, that is set the div error and return inf and nan.
anirudh2290 commentedon May 5, 2020
okay, my bad. inf doesnt really make sense for int.
anirudh2290 commentedon May 5, 2020
Digging into some history, I found this : #7510 , which raises ValueError, the discussion that happened on the issue seems to have converged to this comment : #7510 (comment) . I guess we decided to incrementally fix this and raise ValueError wherever we find such cases ?
anirudh2290 commentedon May 5, 2020
np.power(0, -1) today: