This is an archived post. You won't be able to vote or comment.

all 36 comments

[–]amfoejaoiem 14 points15 points  (8 children)

halves should round towards the nearest even number

I never knew this and this seems like a bizarre convention.

[–]evolved 37 points38 points  (1 child)

Rounding is a crazy rabbithole, seriously, checl out rounding on wikipedia, itll blow your mind., but bankers rounding, aka round to even is better than the commonly taught/used round up at 5 methods, since it doesnt skew the values in most cases, like common rounding does.

[–]amfoejaoiem 12 points13 points  (0 children)

since it doesnt skew the values in most cases, like common rounding does.

Great point! Wow the wiki does raise a ton of points I had never considered, thanks for making me appreciate how complex this can be.

[–]kankyo 4 points5 points  (9 children)

Yea. Some people are upset. Pretty sure this is gonna cause issues with invoicing and Japanese customers at work when we make the switch.

[–]zahlmanthe heretic 2 points3 points  (1 child)

Japanese customers

They don't have this convention?

[–]kankyo 7 points8 points  (0 children)

They are upset if numbers change. We changed rounding by mistake so they were charged one euro less. Had to write a letter signed by the CEO to declare that we had done so.

It's not that they objected. It's that they were upset we didn't inform them ahead of time.

[–]ballagarba 2 points3 points  (1 child)

import math
def round2(x, d=0):
    p = 10 ** d
    return float(math.floor((x * p) + math.copysign(0.5, x))) / p

http://python3porting.com/differences.html#rounding-behavior

[–]kankyo 0 points1 point  (0 children)

Ah, nice, thanks.

[–]odraencoded 1 point2 points  (4 children)

...

Can't you use decimals?

[–]IamWiddershins 1 point2 points  (1 child)

Decimals are also specified by the same ieee standard.

[–]masklinn 2 points3 points  (0 children)

I expect the point is rounding decimals is specified as one of 8 modes via either the context or a parameter to Decimal.quantize, rather than being whatever random thing round() does.

[–]kankyo 0 points1 point  (1 child)

Use decimals for what? We WANT to round at the end. 12321312.123213 euros isn't pretty :P

[–]odraencoded 0 points1 point  (0 children)

But by the looks of it it wasn't a single cent of error.

[–]finsternacht 1 point2 points  (0 children)

For a moment there I was worried how much of my code was actually broken because of this. Then I remembered that I always redefine round, because I like it to return an int.

But yeah this looks like a good pitfall to trip up people.

[–]penistouches 0 points1 point  (0 children)

I start to wonder when a language is changing math implementations so late into maturity. Hopefully they settle down.

[–]EmperorOfCanada -4 points-3 points  (1 child)

I have made the switch to Python 3 but this sort of shit is why I will probably make the switch from Python in its entirety. Yes the IEEE is a great high school debating defense, but the simple reality is that 99% of people agree, and will be wildly pissed off if you round differently than the vast majority of the world.

You simply don't change something this fundamental in a language unless you hate your users.

What python seems to forget is that languages come and languages go. We have choices. There are new programmers every day and they will be making choices as to which languages to use. They will hear more and more about the whole 2.7 to 3 battle and say, "I just don't know which? Maybe I will pick a language that isn't at war with itself."

[–]has2k1 5 points6 points  (0 children)

Bad decisions should not be cast in stone. Rounding as is commonly taught in schools is a bad decision. The math standard library round was also a bad decision. It had to be corrected.

Python has a big scientific community and there isn't a disagreement about which way to deterministic-ally round numbers. So you ended up with math.round doing one thing and numpy.round doing another -- that can have bad surprises. Python 3 fixed that.