Bug Rounding Floats? (9.245 * 100).round => 924? S/B 925!

Discussion in 'Ruby' started by ddoherty03, Jul 22, 2009.

  1. ddoherty03

    ddoherty03 Guest

    All,

    Would someone try the below unit test and explain why ruby does not
    pass. It came up while I was trying to write a generalized rounding
    method for floats that takes the number of place to round to as a
    parameter. It gave wrong answers, but only on rare inputs.

    For example, (9.245 * 100).round should be 925, but my ruby gives 924.

    =================================
    #! /usr/bin/env ruby
    #
    require 'test/unit'

    class TestFloatRounding < Test::Unit::TestCase
    def test_round
    assert_equal(925, 924.5.round, "Rounding Error: 924.5.round")
    assert_equal(9.25, (9.245 * 10.0**2).round / 10.0**2, "Rounding
    Error: (9.245 * 10.0**2).round / 10.0**2")
    assert_equal(925, (9.245 * 10.0**2).round, "Rounding Error:(9.245
    * 10.0**2).round")
    assert_equal(924.5, 9.245 * 10.0**2, "Rounding Error: 9.245 *
    10.0**2")
    assert_equal(925, 924.5.round, "Rounding Error: 924.5.round")
    assert_equal(924.5, 9.245 * 10 * 10, "Rounding Error: 9.245 * 10 *
    10")
    assert_equal(925, (9.245 * 10 * 10).round, "Rounding Error: (9.245
    * 10 * 10).round")
    assert_equal(925.0, 9.245 * 10 * 10 + 0.5, "Rounding Error: 9.245
    * 10 * 10 + 0.5")
    assert_equal(925, (9.245 * 10 * 10 + 0.5).floor, "Rounding Error:
    (9.245 * 10 * 10 + 0.5).floor")
    end
    end
    ===================================
    ddoherty03, Jul 22, 2009
    #1
    1. Advertising

  2. Re: Bug Rounding Floats? (9.245 * 100).round => 924? S/B 925!

    [Note: parts of this message were removed to make it a legal post.]

    2009/7/22 ddoherty03 <>


    > For example, (9.245 * 100).round should be 925, but my ruby gives 924.
    >


    try what your term really is:

    printf("%.50f",9.245 * 100)

    -Thomas

    --
    Thomas Preymesser

    http://thopre.googlepages.com/
    http://thopre.wordpress.com/

    Mike Ditka <http://www.brainyquote.com/quotes/authors/m/mike_ditka.html> -
    "If God had wanted man to play soccer, he wouldn't have given us arms."
    Thomas Preymesser, Jul 22, 2009
    #2
    1. Advertising

  3. ddoherty03

    ddoherty03 Guest

    Re: Bug Rounding Floats? (9.245 * 100).round => 924? S/B 925!

    On Jul 22, 1:13 pm, Glenn Jackman <> wrote:
    > A workaround, convert the expression to a string and back to a number:
    >
    >     num = Float("%.1f" % (9.245 * 100)).round
    >
    >     puts "yippee" if num == 925
    >


    Glenn,

    Thanks for the explanation. If I could pick your brain for a second
    on how to generalize your workaround, I would greatly appreciate it.

    Here is how I tried to implement the "nround" method.

    ######################################
    class Float
    def nround(n = 0)
    (self * 10.0 ** n).round / 10.0 ** n
    end
    end
    ######################################

    My issue is getting the workaround to deal with the parameter n
    properly.

    Regards,
    ddoherty03, Jul 22, 2009
    #3
  4. ddoherty03

    Bil Kleb Guest

    Bil Kleb, Jul 23, 2009
    #4
  5. ddoherty03

    ddoherty03 Guest

    Re: Bug Rounding Floats? (9.245 * 100).round => 924? S/B 925!

    On Jul 23, 9:37 am, Glenn Jackman <> wrote:
    > At 2009-07-22 03:22PM, "ddoherty03" wrote:
    >
    >
    >
    > >  On Jul 22, 1:13 pm, Glenn Jackman <> wrote:
    > > > A workaround, convert the expression to a string and back to a number:
    > > >     num = Float("%.1f" % (9.245 * 100)).round
    > > >     puts "yippee" if num == 925

    >
    > >  Glenn,

    >
    > >  Thanks for the explanation.  If I could pick your brain for a second
    > >  on how to generalize your workaround, I would greatly appreciate it.

    >
    > >  Here is how I tried to implement the "nround" method.

    >
    > >  ######################################
    > >  class Float
    > >    def nround(n = 0)
    > >      (self * 10.0 ** n).round / 10.0 ** n
    > >    end
    > >  end
    > >  ######################################

    >
    > >  My issue is getting the workaround to deal with the parameter n
    > >  properly.

    >
    > Taking Bil Kleb's advice,
    >
    >     require 'bigdecimal'
    >     require 'bigdecimal/util'
    >
    >     class Float
    >       def nround(n=0)
    >         (self.to_d * (10.0**n).to_d).round.to_f / 10.0**n
    >       end
    >     end
    >
    >     p 9.245.nround(2)  # => 9.25
    >
    > --
    > Glenn Jackman
    >     Write a wise saying and your name will live forever. -- Anonymous


    Bil & Glenn & Thomas,

    Thanks. Performance is not a problem, so this works for me.

    Much appreciated.
    ddoherty03, Jul 23, 2009
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Filip Lyncker
    Replies:
    0
    Views:
    544
    Filip Lyncker
    Apr 14, 2005
  2. Terry Hancock

    Interfaces (a la PEP 245 and Zope)

    Terry Hancock, Aug 1, 2003, in forum: Python
    Replies:
    3
    Views:
    269
    Raymond Hettinger
    Aug 2, 2003
  3. Trent Mick
    Replies:
    0
    Views:
    366
    Trent Mick
    Mar 31, 2005
  4. fred
    Replies:
    3
    Views:
    261
    Zifud
    Mar 17, 2005
  5. Replies:
    5
    Views:
    869
Loading...

Share This Page