Re: [Numpy-discussion] Output type of round is inconsistent with python built-in
![](https://secure.gravatar.com/avatar/f9ed6413b67cfa6ddc0a37675d9e065a.jpg?s=120&d=mm&r=g)
There several mixed issues here. 1. PEP 3141 <https://www.python.org/dev/peps/pep-3141/> compliance. Numpy scalars are `numbers.Real` instances, and have to respect the `__round__` semantics defined by PEP 3141: def __round__(self, ndigits:Integral=None): """Rounds self to ndigits decimal places, defaulting to 0. If ndigits is omitted or None, returns an Integral, otherwise returns a Real, preferably of the same type as self. Types may choose which direction to round half. For example, float rounds half toward even. """ This means that if Real -> Real rounding is desired one should call `round(x, 0)` or `np.around(x)`. This semantics only dictates that the return type should be Integral, so for `round(x)` and `round(x, None)` np.float32 -> np.int32 np.float32 -> np.int64 np.float64 -> np.int64 np.floatXX -> int are all OK. I think also that it is perfectly OK to raise an overflow on `round(x)` 2. Liskov substitution principle `np.float64` floats are also `float` instances (but `np.float32` are not.) This means that strictly respecting LSP means that `np.float64` should round to python `int`, since `round(x)` never overflows for python `float`. Here we have several options. - round `np.float64` -> `int` and respect LSP. - relax LSP, and round `np.float64` -> `np.int64`. Who cares about `round(1e300)`? - decide that there is no reason for having `np.float64` a subclass of `float`, so that LSP does not apply. This all said, I think that these are the two most sensible choices for `round(x)`: np.float32 -> np.int32 np.float64 -> np.int64 drop np.float64 subclassing python float or np.float32 -> int np.float64 -> int keep np.float64 subclassing python float The second one seems to me the less disruptive one. Bye Stefano
participants (1)
-
Stefano Miccoli