On Mon, Mar 26, 2018 at 10:03 PM, <josef.p...@gmail.com> wrote:
>
> On Mon, Mar 26, 2018 at 10:29 PM, Robert Kern <robert.k...@gmail.com>
wrote:
> > On Mon, Mar 26, 2018 at 6:28 PM, Nathaniel Smith <n...@pobox.com> wrote:
> >>
> >> On Mon, Mar 26, 2018 at 6:24 PM, Nathaniel Smith <n...@pobox.com> wrote:
> >> > Even knowing that, it's still confusing that round(np.float64(0.0))
> >> > isn't the same as round(0.0). The reason is a Python 2 / Python 3
> >> > thing: in Python 2, round returns a float, while on Python 3, it
> >> > returns an integer – but numpy still uses the python 2 behavior
> >> > everywhere.
> >> >
> >> > I'm not sure if it's possible or worthwhile to change this. If we'd
> >> > changed it when we first added python 3 support then it would have
> >> > been easy (and obviously a good idea), but at this point it might be
> >> > tricky?
> >>
> >> Oh right, and I forgot: part of the reason it's tricky is that it
> >> really would have to return a Python 'int', *not* any of numpy's
> >> integer types, because floats have a much larger range than numpy
> >> integers, e.g.:
> >
> > I don't think that's the tricky part. We don't have to change anything
but
> > our implementation of Python 3's __round__() special method for
np.generic
> > scalar types, which would be straightforward. The only issue, besides
> > backwards compatibility, is that it would introduce a new inconsistency
> > between scalars and arrays (which can't use the Python ints). However,
> > that's "paid for" by the increased compatibility with the rest of
Python.
> > For a special method that is used for to interoperate with a Python
builtin
> > function, that's probably the more important consistency to worry about.
> >
> > As for the backwards compatibility concern, I don't think it would
matter
> > much. Everyone who has written code that expects round(np.float64(...))
to
> > return a np.float64 is probably already wrapping that with int()
anyways.
> > Anyone who really wants to keep the scalar type of the output same as
the
> > input can use np.around().
>
> same would need to apply for ceil, floor, trunc, I guess.

ceil and floor don't have __special__ methods for them; math.ceil() and
math.floor() do not defer their implementation to the type. math.trunc()
might (there is a __trunc__), but it looks like math.trunc(np.float64(...))
already returns an int.

I'm not suggesting changing np.ceil(), np.floor(), etc. Nor am I suggesting
that we change np.around(), np.round(), or the .round() method on scalar
types. Only .__round__().

> However, np.round has a decimal argument that I use pretty often and
> that needs to return a float
>
> >>> np.round(5.33333, 2)
> 5.3300000000000001
>
> Python makes the return type conditional on whether ndigits is used or not
> AFAICS.
> >>> round(5.33333, 0)
> 5.0
> >>> round(5.33333)
> 5

Sorry, I took that as a given. If someone followed my suggestion to
implement np.generic.__round__, yes, they I intended that they handle both
cases correctly.

But also, to reiterate, I'm not suggesting that we change np.round(). Only
the behavior of numpy scalar types under the builtin round() function.

--
Robert Kern
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion

Reply via email to