Skip to content

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

@LiquidFun

Description

@LiquidFun

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions