Skip to content

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

Closed

Description

@will133

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).

Activity

  1. charris commented on Jun 6, 2016

    @charris
    Member

    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.

  2. mhvk commented on Jun 6, 2016

    @mhvk
    Contributor

    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.

  3. charris commented on Jun 6, 2016

    @charris
    Member

    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.

  4. njsmith commented on Jun 10, 2016

    @njsmith
    Member

    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...

  5. mhvk commented on Jun 10, 2016

    @mhvk
    Contributor

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

  6. charris commented on Jun 10, 2016

    @charris
    Member

    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...

  7. charris commented on Jun 10, 2016

    @charris
    Member

    @jreback Thoughts...

  8. jreback commented on Jun 10, 2016

    @jreback

    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
    
  9. charris commented on Jun 10, 2016

    @charris
    Member

    @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.

  10. seberg commented on Jun 11, 2016

    @seberg
    Member

    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.

  11. seberg commented on Nov 19, 2022

    @seberg
    Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions