round(numpy.float64(0.0)) is a numpy.float64
![](https://secure.gravatar.com/avatar/225f9598f1d35baa94f2e1cc5bee6103.jpg?s=120&d=mm&r=g)
Hello, Is it normal, expected and desired that : round(numpy.float64(0.0)) is a numpy.float64 while round(numpy.float(0.0)) is an integer? I find it disturbing and misleading. What do you think? Has it already been discussed somewhere else? Best regards, Olivier
![](https://secure.gravatar.com/avatar/7857f26c1ef2e9bdbfa843f9087710f7.jpg?s=120&d=mm&r=g)
numpy.float is an alias to the python float builtin. https://github.com/numpy/numpy/issues/3998 On Thu, Mar 22, 2018 at 2:26 PM Olivier <oc-spam66@laposte.net> wrote:
Hello,
Is it normal, expected and desired that :
round(numpy.float64(0.0)) is a numpy.float64
while
round(numpy.float(0.0)) is an integer?
I find it disturbing and misleading. What do you think? Has it already been discussed somewhere else?
Best regards,
Olivier
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/97c543aca1ac7bbcfb5279d0300c8330.jpg?s=120&d=mm&r=g)
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? -n On Thu, Mar 22, 2018 at 12:32 PM, Nathan Goldbaum <nathan12343@gmail.com> wrote:
numpy.float is an alias to the python float builtin.
https://github.com/numpy/numpy/issues/3998
On Thu, Mar 22, 2018 at 2:26 PM Olivier <oc-spam66@laposte.net> wrote:
Hello,
Is it normal, expected and desired that :
round(numpy.float64(0.0)) is a numpy.float64
while
round(numpy.float(0.0)) is an integer?
I find it disturbing and misleading. What do you think? Has it already been discussed somewhere else?
Best regards,
Olivier
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
-- Nathaniel J. Smith -- https://vorpus.org
![](https://secure.gravatar.com/avatar/97c543aca1ac7bbcfb5279d0300c8330.jpg?s=120&d=mm&r=g)
On Mon, Mar 26, 2018 at 6:24 PM, Nathaniel Smith <njs@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.: In [4]: round(1e50) Out[4]: 100000000000000007629769841091887003294964970946560 In [5]: round(np.float64(1e50)) Out[5]: 1e+50 In [6]: np.uint64(round(np.float64(1e50))) Out[6]: 0 (Actually that last case illustrates another weird inconsistency: np.uint64(1e50) -> OverflowError, but np.uint64(np.float64(1e50)) -> 0. I have no idea what's going on there.) -n -- Nathaniel J. Smith -- https://vorpus.org
![](https://secure.gravatar.com/avatar/764323a14e554c97ab74177e0bce51d4.jpg?s=120&d=mm&r=g)
On Mon, Mar 26, 2018 at 6:28 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Mon, Mar 26, 2018 at 6:24 PM, Nathaniel Smith <njs@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(). -- Robert Kern
![](https://secure.gravatar.com/avatar/ad13088a623822caf74e635a68a55eae.jpg?s=120&d=mm&r=g)
On Mon, Mar 26, 2018 at 10:29 PM, Robert Kern <robert.kern@gmail.com> wrote:
On Mon, Mar 26, 2018 at 6:28 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Mon, Mar 26, 2018 at 6:24 PM, Nathaniel Smith <njs@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. 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
(I'm currently using Python 3.4.4) Josef
-- Robert Kern
_______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@python.org https://mail.python.org/mailman/listinfo/numpy-discussion
![](https://secure.gravatar.com/avatar/764323a14e554c97ab74177e0bce51d4.jpg?s=120&d=mm&r=g)
On Mon, Mar 26, 2018 at 10:03 PM, <josef.pktd@gmail.com> wrote:
On Mon, Mar 26, 2018 at 10:29 PM, Robert Kern <robert.kern@gmail.com>
On Mon, Mar 26, 2018 at 6:28 PM, Nathaniel Smith <njs@pobox.com> wrote:
On Mon, Mar 26, 2018 at 6:24 PM, Nathaniel Smith <njs@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
wrote: 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
participants (5)
-
josef.pktd@gmail.com
-
Nathan Goldbaum
-
Nathaniel Smith
-
Olivier
-
Robert Kern