8000 numpy 1.11 has different floordiv behavior on infinity and 0 comparing to numpy 1.10 · Issue #7709 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

numpy 1.11 has different floordiv behavior on infinity and 0 comparing to numpy 1.10 #7709

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

Closed
will133 opened this issue Jun 6, 2016 · 11 comments

Comments

@will133
Copy link
will133 commented Jun 6, 2016

I'm getting a different floordiv behavior when switching from 1.10 to 1.11. Is this intentional? It seems more inconsistent comparing to the normal division behavior:

# Old (numpy 1.10):
>>> import numpy
>>> x = numpy.float64(12.)
>>> x // 0.
inf
>>> x // numpy.inf
0.0
>>> x / 0.
inf
>>> x / numpy.inf
0.0

# New (numpy 1.11):
>>> import numpy
>>> x = numpy.float64(12.)
# Why nan?
>>> x // 0.
nan
# Why -0.0 when 12. is a positive number on a positive inf?
>>> x // numpy.inf
-0.0
>>> x / 0.
inf
>>> x / numpy.inf
0.0

This is on Linux 64-bit (numpy 1.11.0) from the conda environment with git_revision (4092a9e).

@charris
Copy link
Member
charris commented Jun 6, 2016

Floor division is now computed using divmod so that it is compatible with %. divmod in turn is based around fmod as in python, indeed, the implementation is taken from python. See #7258. The nan is used so that the function can be used for arrays, whereas python raises a ZeroDivisionError. We could possibly adjust the behavior for numpy scalars to raise a error, but it is probably better to remain compatible with arrays and array scalars. The -0.0 looks like a bug.

@mhvk
Copy link
Contributor
mhvk commented Jun 6, 2016

Mathematically, I guess divmod(12., 0.) should be inf, nan, not nan, nan. In principle, since there is already a separate path for b=0, it would not take lead to any slowdown for the main path to assign a properly signed infinity.

On the sign: almost certainly related to testing for sign of ratio as (a / b) > 0.

@charris
Copy link
Member
charris commented Jun 6, 2016

I guess divmod(12., 0.) should be inf, nan, not nan, nan

I thought about that, but as I was replacing a ZeroDivisionError, nan, nan seemed more appropriate. It is an arguable point.

@njsmith
Copy link
Member
njsmith commented Jun 10, 2016

as I was replacing a ZeroDivisionError, nan seemed more appropriate

In regular float division we replace ZeroDivisionError with inf, though (as required by IEEE754):

In [1]: 1.0 / 0.0
---------------------------------------------------------------------------
ZeroDivisionError                         Traceback (most recent call last)
<ipython-input-1-42176c28e89e> in <module>()
----> 1 1.0 / 0.0

ZeroDivisionError: float division by zero

In [2]: np.divide(1.0, 0.0)
/home/njs/.user-python3.5-64bit/bin/ipython:1: RuntimeWarning: divide by zero encountered in true_divide
  #!/home/njs/.user-python3.5-64bit/bin/python3.5
Out[2]: inf

So I guess I agree that returning inf makes more sense, though I also agree that it isn't super clear...

@mhvk
Copy link
Contributor
mhvk commented Jun 10, 2016

Yes, my logic was 1 / 0 = inf, 1 // 0 = inf, and 1 / 0 - 1 // 0 = inf - inf = nan.

@charris
Copy link
Member
charris commented Jun 10, 2016

The argument for the other way round is that the divmod function determines the remainder first rather than doing a division. However, if +/- inf seems a better choice to most I'll happily change it before current behavior get too widespread. IIRC, the original changes broke some pandas tests which were fixed...

@charris
Copy link
Member
charris commented Jun 10, 2016

@jreback Thoughts...

@jreback
Copy link
jreback commented Jun 10, 2016

This is the behavior in pandas master, which I think matches. On integers we do return a NaN on // though.

In [1]: s = Series([12])

In [2]: s // 0
Out[2]: 
0    inf
dtype: float64

In [3]: s / np.inf
Out[3]: 
0    0.0
dtype: float64

In [4]: s / 0.
Out[4]: 
0    inf
dtype: float64

In [5]: s = Series([12.])

In [6]: s // 0
Out[6]: 
0   NaN
dtype: float64

In [7]: s / np.inf
Out[7]: 
0    0.0
dtype: float64

@charris
Copy link
Member
charris commented Jun 10, 2016

@jreback Any preference on how it ought to behave? Note that current behavior doesn't keep me up at nights, but if we want to change it, it should be before 1.12.

@seberg
Copy link
Member
seberg commented Jun 11, 2016

np.floor(np.inf) == np.inf`, so I think I have a slight tendency to prefer infinity as well. Not sure how it plays with divmod though.

@seberg
Copy link
Member
seberg commented Nov 19, 2022

This seems fixed now, giving inf for floor division and inf+nan for divmod.

@seberg seberg closed this as completed Nov 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants
0