Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Change default rounding mode to TIES_EVEN #10414

Closed
straight-shoota opened this issue Feb 18, 2021 · 10 comments · Fixed by #10508
Closed

Change default rounding mode to TIES_EVEN #10414

straight-shoota opened this issue Feb 18, 2021 · 10 comments · Fixed by #10508

Comments

@straight-shoota
Copy link
Member

#10413 introduces a new rounding mode which rounds ties to the next even number (also known as "Banker's roundin").

This rounding mode should be used as default for Number#round. The current default, TIES_AWAY has a bias towards larger magnitude.

TIES_EVEN is recommended as dedault mode by IEEE-754 and many other languages use it as default including Julia, libc, Java.

@straight-shoota
Copy link
Member Author

straight-shoota commented Mar 13, 2021

This might be controversial, but should we change this before 1.0? It's probably better to change now than any point later.

@bcardiff
Copy link
Member

I'm on board with changing it for 1.0. Other languages allow setting the default rounding mode. Should we consider the same? It can appear later of needed.

@asterite
Copy link
Member

@bcardiff do you mean globally?

@bcardiff
Copy link
Member

Yes

@asterite
Copy link
Member

Is there any other language that allows that? Well, maybe if it's a compile flag... But then, what if a lib expects a default round mode but you change it?

Or what would be the use case? If the default is configurable then you would always want to specify a value to make sure you get the behavior you want, making the default useless.

@Sija
Copy link
Contributor

Sija commented Mar 13, 2021

Is there any other language that allows that? [...]

@asterite Yes, Ruby - for BigDecimal at least.

@bcardiff
Copy link
Member

Julia, libc and java links shared previously shows how to set the current global rounding mode. That's why I mentioned it.

For apps it might not be useful. For numerical processing it might.

Again, is not mandatory on my end.

@straight-shoota
Copy link
Member Author

straight-shoota commented Mar 13, 2021

A number of languages have global configuration. Julia and libc as noted in the OP.

Java on the other hand has a MathContext class which can be tied directly to BigDecimal number instances and then all operations on that instance uses the configured rounding mode.

I'm not very familiar with the specifics though. We shouldn't rush an implemementation. Having a global setting would surely be nice to offer a fallback mechanic. But is should be fine with just changing the default. If it breaks someone's code and they need to change the default rounding mode back globally, it's always possible to re-implement Number#round.

@contentfree
Copy link

contentfree commented Mar 29, 2021

For people in the future who will undoubtedly be confused by the new default: Does this mean we should expect 0.5 to round to 0, 1.5 to round to 2, 2.5 to also round to 2, and 3.5 to round to 4, etc? As opposed to the rules many of were taught as children to "round up when equidistant" (which I believe is the "rounds away [from zero]" method).

@straight-shoota
Copy link
Member Author

straight-shoota commented Mar 29, 2021

Yes, exactly. The new TIES_EVEN mode breaks ties by rounding to the nearest even number.

No doubt this may be confusing when you expect TIES_AWAY which is commonly used in every-day maths and typically tought in school.

TIES_EVEN is preferred however in computational algebra because it is less biased and minimizes the expected error for sums of rounded numbers.

To show this in an example.

numbers = [0.5, 1.5, 2.5, 3.5, 4.5]

numbers.sum                      # => 12.5
numbers.sum(&.round(:ties_even)) # => 12.0
numbers.sum(&.round(:ties_away)) # => 15.0

The actual sum of these five numbers is 12.5. With rounded values, the sum is 12.0 for TIES_EVEN mode. The difference is a small error due to rounding. With TIES_AWAY mode the difference is much larger at 15.0.
This example is obviously rigged to demonstrate the effect drastically, but the fact is that this error shows in any larger set of mostly unrelated figures.

Thus TIES_AWAY is considered a better rounding mode for these kind of operations which happen a lot in computer programs. It has some other drawbacks of course, but is generally preferred over TIES_AWAY.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants