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