Behaviour of round changed?

I am moving some algorithms between 1.9.3 and 2.4.2 and found (after much
head scratching)

2.4.2 :001 > 1.015.round(2)
=> 1.02

1.9.3-p551 :001 > 1.015.round(2)
=> 1.01

We are calculating margin prices and round input values to 2 places because
the precision is not needed and it can help with caching

The tests broke :frowning:

Let me see if I understand this, Ruby has changed how basic maths functions
work

Can I trust ceil, floor, truncate or any of the other number related
functions?

Do I need to write tests for the language itself for when I upgrade to a
newer version in the future or should I stick with 1.9.3 for all eternity?

A change at this low a level is almost impossible to speculatively test
for, if I cannot trust the language I am using I cannot trust my code at all

I am now in a position of having to test my code to an excessive degree
because I cannot trust there are not any other changes that will be
triggered on some previously innocent edge case

I am extremely pissed off right now

It's late here, so I can only be quick:

1. Don't ever use floats for money.

2. It was documented in the release notes for 2.4.0
<https://docs.ruby-lang.org/en/2.4.0/NEWS.html&gt;

    "Float#round now takes an optional keyword argument, half option,
and the default behavior is round-to-nearest-even now. [Bug #12548]"

3. See these tickets in the bug tracker for some history on the #round changes:

    * Bug #12548: Rounding modes inconsistency between round versus sprintf - Ruby master - Ruby Issue Tracking System
    * Bug #12958: Breaking change in how `#round` works - Ruby master - Ruby Issue Tracking System
    * Feature #12953: (Float, Integer, Rational)#round(half: :down) - Ruby master - Ruby Issue Tracking System

4. Even Ruby 2.4 is old now; 2.6.0 has been released...

5. Don't ever use floats for money.

Cheers

路路路

On Tue, 8 Jan 2019 at 23:17, Peter Hickman <peterhickman386@googlemail.com> wrote:

I am moving some algorithms between 1.9.3 and 2.4.2 and found (after much head scratching)

2.4.2 :001 > 1.015.round(2)
=> 1.02

1.9.3-p551 :001 > 1.015.round(2)
=> 1.01

We are calculating margin prices and round input values to 2 places because the precision is not needed and it can help with caching

The tests broke :frowning:

Let me see if I understand this, Ruby has changed how basic maths functions work

Can I trust ceil, floor, truncate or any of the other number related functions?

Do I need to write tests for the language itself for when I upgrade to a newer version in the future or should I stick with 1.9.3 for all eternity?

A change at this low a level is almost impossible to speculatively test for, if I cannot trust the language I am using I cannot trust my code at all

I am now in a position of having to test my code to an excessive degree because I cannot trust there are not any other changes that will be triggered on some previously innocent edge case

I am extremely pissed off right now

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk&gt;

--
  Matthew Kerwin
  https://matthew.kerwin.net.au/

IIRC it鈥檚 just round. A decision was made to round to the nearest even number in case of a tie, rather than to round down. This is the more standard approach?

I think this is the relevant issue: https://bugs.ruby-lang.org/issues/12548

路路路

From: ruby-talk [mailto:ruby-talk-bounces@ruby-lang.org] On Behalf Of Peter Hickman
Sent: 08 January 2019 13:15
To: ruby-talk ML
Subject: Behaviour of round changed?

I am moving some algorithms between 1.9.3 and 2.4.2 and found (after much head scratching)

2.4.2 :001 > 1.015.round(2)
=> 1.02

1.9.3-p551 :001 > 1.015.round(2)
=> 1.01

We are calculating margin prices and round input values to 2 places because the precision is not needed and it can help with caching

The tests broke :frowning:

Let me see if I understand this, Ruby has changed how basic maths functions work

Can I trust ceil, floor, truncate or any of the other number related functions?

Do I need to write tests for the language itself for when I upgrade to a newer version in the future or should I stick with 1.9.3 for all eternity?

A change at this low a level is almost impossible to speculatively test for, if I cannot trust the language I am using I cannot trust my code at all

I am now in a position of having to test my code to an excessive degree because I cannot trust there are not any other changes that will be triggered on some previously innocent edge case

I am extremely pissed off right now

Click here to view Company Information and Confidentiality Notice.<http://www.jameshall.co.uk/index.php/small-print/email-disclaimer>

Please note that we have updated our privacy policy in line with new data protection regulations. Please refer to our website to view the ways in which we handle your data.

Let me emphasize what Matthew already said: you should never, ever use
floats to represent money. Rounding, lack of precision, comparisons - all
that makes floats unreliable for dealing with monetary amounts.

Best regards
Greg Navis

Thanks, I get the money thing but this is price as used in calculating odds
in betting. Price is an idealised value, not monetary (no accountants
involved :))

The calculation needs to be reliable. Given a set of inputs is should
return the same outputs. In this situation we have code changing it's
outputs depending on which version of Ruby is running it

I'm glad that it is just round that has been affected and that it was a
conscious decision but I have some not inconsiderable blobs of maths for
pricing (in betting) and libraries that are used to support it

I can grep for round but the thought that I couldn't trust any number based
function is truly terrifying

Thanks, I get the money thing but this is price as used in calculating odds

in betting. Price is an idealised value, not monetary (no accountants
involved :))

I once worked on a betting platform and chose rationals all the way down to
Postgres :slight_smile:

    https://www.youtube.com/watch?v=tT72TlmhgL4

Maybe your choice is good, can't tell without knowing the details, but be
super vigilant of the assumptions!

路路路

On Tue, Jan 8, 2019 at 3:53 PM Peter Hickman <peterhickman386@googlemail.com> wrote: