(Not a NumPy-dev, but here goes. Probably some of the discussions are "too
basic", but hard to say which.)

I would take it that round x to N radix-R digits means
round_to_integer(x * R**N)/R**N
(ignoring floating-point issues)

Now, we can discuss what round to integer means. There, the major
difference among round-to-nearest-approaches is how to handle ties (sort of
what your example shows, although it is more a consequence of a limitation
than a different rounding mode). Even with decimal representations you will
need to define which of the supported rounding modes are used, something
that is typically not accessible for users (in Python not accessible at all
AFAICT).

Based on standard school rounding (to nearest), tie to even is the norm
(and is the default in IEEE 754), which seems to be what NumPy states that
it does https://numpy.org/doc/stable/reference/generated/numpy.round.html
"For values exactly halfway between rounded decimal values, NumPy rounds to
the nearest even value. Thus 1.5 and 2.5 round to 2.0, -0.5 and 0.5 round
to 0.0, etc."

For use cases, I believe something like representing currency with,
typically, two decimal digits, is a pretty good use case. However, it is
hard to argue against your claim that one should probably use decimal
representations instead. Still, for approximately correct computation,
typically much faster as decimal support is scarce in hardware, where the
need is more or less to get "good looking numbers" it still makes sense.
Hence, one can probably say that it will be inexact anyway and maybe the
discussion in the docs is enough. (For your example, NumPy is actually more
correct than CPython. There are probably cases the other way around as well
though.)

One may think that an additional optional argument, specifying rounding
mode, could make sense. However, since the purpose of np.round seems to be
performance (as otherwise one could just have wrapped/imitated Python's
round), this may remove parts of the benefit.

I can also recommend the thread pointed out in the previous answer. (Didn't
read it before starting writing this.) Quite a lot of interesting
discussions, especially the legacy argument.

BR Oscar Gustafsson

(FWIW, I suggested that NumPy should be able to round to a given number of
bits, or arbitrary base, primarily as a way to fake (short) fixed-point
representations, but that was turned down as not really wanted as part of
the core library. So there is a separate library for NumPy-like fixed-point
numbers in development, with "all" possible rounding/quantization methods
supported. Anyone can feel free to contact me for more info, but I will
announce it, once in a usable enough state.)


Den tors 28 dec. 2023 kl 22:46 skrev Stefano Miccoli via NumPy-Discussion <
numpy-discussion@python.org>:

> I have always been puzzled about how to correctly define the python
> built-in `round(number, ndigits)` when `number` is a binary float and
> `ndigits` is greater than zero.
> Apparently CPython and numpy disagree:
>         >>> round(2.765, 2)
>         2.77
>         >>> np.round(2.765, 2)
>         2.76
>
> My question for the numpy devs are:
> - Is there an authoritative source that explains what `round(number,
> ndigits)` means when the digits are counted in a base different from the
> one used in the floating point representation?
> - Which was the first programming language to implement an intrinsic
> function `round(number, ndigits)` where ndgits are always decimal,
> irrespective of the representation of the floating point number? (I’m not
> interested in algorithms for printing a decimal representation, but in
> languages that allow to store and perform computations with the rounded
> value.)
> - Is `round(number, ndigits)` a useful function that deserves a rigorous
> definition, or is its use limited to fuzzy situations, where accuracy can
> be safely traded for speed?
>
> Personally I cannot think of sensible uses of `round(number, ndigits)` for
> binary floats: whenever you positively need `round(number, ndigits)`, you
> should use a decimal floating point representation.
>
> Stefano_______________________________________________
> NumPy-Discussion mailing list -- numpy-discussion@python.org
> To unsubscribe send an email to numpy-discussion-le...@python.org
> https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> Member address: oscar.gustafs...@gmail.com
>
_______________________________________________
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com

Reply via email to