
In Python there is a operation for floor division: a // b. Ceil division easy can be expressed via floor division: -((-a) // b). But round division is more complicated. This operation is needed in Fraction.__round__, in a number of methods in the datetime module (see _divide_and_round). Due to the complexity of the correct Python implementation, it is slower then just division. I propose to add special function in the math module. This not only will speed up Python implementation of the datetime module and the fractions module, but will encourage users to use correct algorithm instead of obvious but incorrect round(a/b).

Pardon my ignorance, but what is the definition of round division? (if it isn't "round(a/b)")

On 10 September 2015 at 22:13, Mark Young <marky1991@gmail.com> wrote:
Pardon my ignorance, but what is the definition of round division? (if it isn't "round(a/b)")
I assumed it would be "what round(a/b) would give if it weren't subject to weird floating point rounding issues". To put it another way, if a / b is d remainder r, then I'd assume "round division" would be d if r < b/2, d+1 if r > b/2, and (which of d, d+1?) if r == b/2. (a, b, d and r are all integers). If not, then I also would like to know what it means... Either way, if it is introduced then it should be documented (particularly as regards what happens when one or both of a, b are negative) clearly, as it's not 100% obvious. Also, is the math module the right place? All of the operations in the math module (apart from factorial, for some reason...) are floating point. Paul

On 11.09.15 00:48, Paul Moore wrote:
Yes, it is what you have described. If r == b/2, the result is even (i.e. (d+1)//2*2).
It is the best place in the stdlib. Apart from floating point functions, the math module contains integer functions (factorial and gcd) and general number functions (floor, ceil, trunc and isclose). gcd and isclose are new in 3.5.

On Thu, Sep 10, 2015 at 3:39 PM, Serhiy Storchaka <storchaka@gmail.com> wrote:
well, floor, ceil, and isclose are all about floats... Nevertheless, yes the math module is the place for it. -CHB
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Fri, Sep 11, 2015 at 01:39:59AM +0300, Serhiy Storchaka wrote:
How does this differ from round(a/b)? round() also rounds to even. Perhaps a more general solution would be a round-to-direction, or divide-and-round-to-direction. Now that we have Enums, we could define enums for round-to-zero, round-to-nearest, round-to-infinity, round-to-even, and have a function divide(a, b, dir=ROUNDEVEN), say. -- Steve

On Sep 10, 2015, at 20:13, Steven D'Aprano <steve@pearwood.info> wrote:
His rounds based on the exact integer remainder; yours rounds based on the inexact float fractional part. So, if b is large enough, using round division is guaranteed to do the right thing,[1] but rounding float division may have rounding, overflow, or underflow errors. [1] Except I'm pretty sure he wants to compare r*2 to b, not r to b/2. Otherwise he's reintroduced the problem he's trying to solve.

Pardon my ignorance, but what is the definition of round division? (if it isn't "round(a/b)")

On 10 September 2015 at 22:13, Mark Young <marky1991@gmail.com> wrote:
Pardon my ignorance, but what is the definition of round division? (if it isn't "round(a/b)")
I assumed it would be "what round(a/b) would give if it weren't subject to weird floating point rounding issues". To put it another way, if a / b is d remainder r, then I'd assume "round division" would be d if r < b/2, d+1 if r > b/2, and (which of d, d+1?) if r == b/2. (a, b, d and r are all integers). If not, then I also would like to know what it means... Either way, if it is introduced then it should be documented (particularly as regards what happens when one or both of a, b are negative) clearly, as it's not 100% obvious. Also, is the math module the right place? All of the operations in the math module (apart from factorial, for some reason...) are floating point. Paul

On 11.09.15 00:48, Paul Moore wrote:
Yes, it is what you have described. If r == b/2, the result is even (i.e. (d+1)//2*2).
It is the best place in the stdlib. Apart from floating point functions, the math module contains integer functions (factorial and gcd) and general number functions (floor, ceil, trunc and isclose). gcd and isclose are new in 3.5.

On Thu, Sep 10, 2015 at 3:39 PM, Serhiy Storchaka <storchaka@gmail.com> wrote:
well, floor, ceil, and isclose are all about floats... Nevertheless, yes the math module is the place for it. -CHB
-- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@noaa.gov

On Fri, Sep 11, 2015 at 01:39:59AM +0300, Serhiy Storchaka wrote:
How does this differ from round(a/b)? round() also rounds to even. Perhaps a more general solution would be a round-to-direction, or divide-and-round-to-direction. Now that we have Enums, we could define enums for round-to-zero, round-to-nearest, round-to-infinity, round-to-even, and have a function divide(a, b, dir=ROUNDEVEN), say. -- Steve

On Sep 10, 2015, at 20:13, Steven D'Aprano <steve@pearwood.info> wrote:
His rounds based on the exact integer remainder; yours rounds based on the inexact float fractional part. So, if b is large enough, using round division is guaranteed to do the right thing,[1] but rounding float division may have rounding, overflow, or underflow errors. [1] Except I'm pretty sure he wants to compare r*2 to b, not r to b/2. Otherwise he's reintroduced the problem he's trying to solve.
participants (9)
-
Andrew Barnert
-
Chris Barker
-
Emile van Sebille
-
Guido van Rossum
-
Mark Young
-
Paul Moore
-
Serhiy Storchaka
-
Stephen J. Turnbull
-
Steven D'Aprano