Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

Another rounding problem in number_with_precision

#6182

Currently, if you run number_with_precision(9.995, :precision => 2) it returns "9.99". It should return "10.00". You can read a little more information here:

http://stackoverflow.com/questions/4241879/number-to-currency-round...

It basically comes down to this:

# File actionpack/lib/action_view/helpers/number_helper.rb, line 280
rounded_number = BigDecimal.new((number * (10 ** precision)).to_s).round.to_f / 10 ** precision

You can see here that the number is multiplied by 100 before it is converted to BigDecimal. When working with Floats, 9.995 * 100 = 999.4999999999999 which will obviously round down to 999, not up to 1000.

My Fix

I have attached a patch for this that just uses the BigDecimal round function which does this perfectly. In the case where significant is true, it just converts the number to BigDecimal before doing its rounding, etc.

Let me know what you think!

Reported by Don Wilson · December 16th, 2010 @ 08:01 PM

State: resolved
Milestone: 3.0.5
Assigned to: Piotr Sarnacki Piotr Sarnacki
Importance: Low

Activity

  1. Piotr Sarnacki
    Piotr Sarnacki
    • Importance changed from to Low

    I would apply this patch, but it works only on 1.9, on 1.8 I get one failure:

    1) Failure:
    test_number_with_precision(NumberHelperTest)
        [./test/template/number_helper_test.rb:105:in `test_number_with_precision'
         /users/drogus/projekty/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:67:in `__send__'
         /users/drogus/projekty/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:67:in `run'
         /users/drogus/projekty/rails/activesupport/lib/active_support/callbacks.rb:426:in `_run_setup_callbacks'
         /users/drogus/projekty/rails/activesupport/lib/active_support/testing/setup_and_teardown.rb:65:in `run']:
    <"10.0"> expected but was
    <"9.99">.
    

    December 17th, 2010 @ 11:05 AM

  2. Repository
    Repository
    • State changed from new to resolved

    December 17th, 2010 @ 03:11 PM

  3. Repository
    Repository

    (from [07567aea5f0c6f14a53f511ab4cc46201b669795]) Revert "Fixed number_with_precision rounding error [#6182 state:resolved]"

    This reverts commit 006ec77e60163d57d655479602230672d98e0f10.
    https://github.com/rails/rails/commit/07567aea5f0c6f14a53f511ab4cc4...

    December 17th, 2010 @ 03:13 PM

  4. Piotr Sarnacki
    Piotr Sarnacki
    • Milestone cleared.
    • State changed from resolved to open
    • Assigned user set to Piotr Sarnacki

    Awww... sorry guys, I accidently applied that to master and pushed with other fix. I've reverted it now, so it's still open.

    Don: please let me know on your findings about that failing test.

    December 17th, 2010 @ 03:16 PM

  5. Don Wilson
    Don Wilson

    Good catch Piotr :)

    In certain cases in Ruby 1.8, BigDecimal / Float = Float. So, I just had to convert the other side to a BigDecimal before the division.

    Just a note, when I convert it to BigDecimal, I have a to_f before the to_s. This was necessary because in Ruby 1.9, many times it is not a Float already, it is a Rational. When you do to_s on a Rational it looks like this "(1/100)". Then, BigDecimal doesn't read it correctly and thinks that you meant 1.0 instead of 0.01.

    I have attached a new patch.

    December 17th, 2010 @ 05:06 PM

  6. Repository
    Repository
    • State changed from open to resolved

    December 18th, 2010 @ 09:55 AM

  7. Repository
  8. Santiago Pastorino