Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Both round() and numpy.round() in Python 3 round to the nearest even number for *.5 numbers (i.e., round(0.5) == 0) #267

Closed
LiquidFun opened this issue May 6, 2021 · 1 comment · Fixed by #268

Comments

@LiquidFun
Copy link
Contributor

In Python 3 round() and numpy.round() both round to the nearest even number whenever a number ends in .5:

[ins] In [1]: round(0.5)
Out[1]: 0

[ins] In [2]: round(1.5)
Out[2]: 2

[ins] In [3]: round(2.5)
Out[3]: 2

[ins] In [4]: import numpy

[ins] In [5]: numpy.round(0.5)
Out[5]: 0.0

[ins] In [6]: numpy.round(1.5)
Out[6]: 2.0

[ins] In [7]: numpy.round(2.5)
Out[7]: 2.0

I know there are already two closed issues discussing this (1, 2), but both only mention rounding to the n-th digit (round(1.25, 1) == 1.2) which does not feel as impactful. The latter also claims this is not Python related, but according to this stackoverflow thread, it was a conscious decision to change this from the old expected behavior during the switch from Python 2 to 3. As in, it is not a mistake or a side-effect of floating point numbers. In short, it is called banker's rounding, and is done to reduce the bias which appears when always rounding upwards in the *.5 cases. But in the answer kindall also says that this "is considered the standard rounding method", so I have tried some languages:

Javascript:

Math.round(0.5)
1
Math.round(1.5)
2
Math.round(2.5)
3

Ruby:

irb(main):004:0> 0.5.round()
=> 1
irb(main):005:0> 1.5.round()
=> 2
irb(main):006:0> 2.5.round()
=> 3

C/C++:

#include <iostream>
#include <math.h>
int main() {
    std::cout << round(0.5) << std::endl;
    std::cout << round(1.5) << std::endl;
    std::cout << round(2.5) << std::endl;
}
// Output:
// 1
// 2
// 3

Also tested in Rust and Java with the same outcome. I have not tested more languages, so it would be interesting to know whether some other popular ones do actually implement banker's rounding, but I could not find any (the stackoverflow answer does mention AppleScript). Although I do think this kind of rounding idea is kind of neat, it does not seem to be the standard in some of the most popular languages out there. It's also not what is taught in school in terms of rounding (at least for me). I was very surprised to find this today (and not find it in this repo), resulting in a large wtf moment. What do you think? Does this fit into wtfpython, as it seems to be quite specific to Python?

@satwikkansal
Copy link
Owner

I think you're correct, it is surprising that it does not always round to a lower number or higher number. Surprising because most people don't know about Banker's Rounding (including me, until now). And the fact that other languages have a different behaviour doesn't make it simpler. It is also subtle in the sense that no one would pay attention to it until their end calculations seem off or they are genuinely curious about such aspects of their program.

That's all to say, I'm happy to see this as a part of the collection. I should have dug deeper into it at the time when I discovered it. Feel free to make a PR if you have any free time (would really appreciate it). Otherwise, I'll add it in the next batch update.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants