205

How do you round a float to 2 decimal places in JRuby(1.6.x)?

number = 1.1164
number.round(2)

# The above shows the following error
# wrong number of arguments (1 for 0)
BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Sam
  • 8,387
  • 19
  • 62
  • 97

6 Answers6

346
(5.65235534).round(2)
#=> 5.65
boulder_ruby
  • 38,457
  • 9
  • 79
  • 100
  • 23
    `(5.6).round(2)` is returning only 5.6 – Bala Karthik Jul 12 '16 at 10:27
  • 6
    seems reasonable, that extra zero placeholder is still there, its just not visible – boulder_ruby Oct 24 '16 at 02:44
  • @BalaKarthik That is the very reason why I am using the solution by Theo. It rounds correctly (except if you're going past 3 decimals for some odd reason, see comments), so that is the better solution if you are looking for string output. – Dylan Vander Berg Aug 06 '17 at 04:33
  • this is right. I was generation random latitude and longitude so I use number.round(6) for 6 digits – gsumk Sep 12 '19 at 15:14
239

sprintf('%.2f', number) is a cryptic, but very powerful way of formatting numbers. The result is always a string, but since you're rounding I assume you're doing it for presentation purposes anyway. sprintf can format any number almost any way you like, and lots more.

Full sprintf documentation: http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-sprintf

quinn
  • 5,508
  • 10
  • 34
  • 54
Theo
  • 131,503
  • 21
  • 160
  • 205
  • 96
    `'%.2f' % number` also works is more commonly seen, at least in my experience. – Michael Kohl May 10 '12 at 20:52
  • 6
    @MichaelKohl The [ruby style guide](https://github.com/bbatsov/ruby-style-guide#sprintf) favours `sprintf` (or `format`) over the `%` version. Some reasoning for that is discussed [here](http://batsov.com/articles/2013/06/27/the-elements-of-style-in-ruby-number-2-favor-sprintf-format-over-string-number-percent/), it's mostly about readability. Not that we all have to follow the style guide, just giving some reasons :) – Lucy Bain Sep 04 '14 at 01:10
  • 4
    note that after the 3rd decimal, sprintf rounds up on 6, not on 5, for instance, sprintf("%.3f", 1.2225) will be "1.222", sprintf("%.3f", 1.2226) will be "1.223", if that matters to you, stick to using #round – ecoding5 Feb 26 '16 at 18:05
  • But `0.566666666666666` rounds to `0.57` – Anwar Apr 05 '16 at 18:22
  • 1
    `"%.2f"` rounds `5` down, instead of up, is there any way to fix that? – Mirror318 Jun 14 '16 at 23:37
  • @Anwar what is wrong with that? That's how rounding is supposed to work and does same for `.round(2)`. @Mirror318 are you sure about that? What is your example and on which version of ruby? – lacostenycoder Jan 05 '20 at 10:54
  • this should be marked as the correct answer. – Hamdan Dec 06 '20 at 18:36
  • This produces a string, it should not be the correct answer for this question. You could run into issues if you have code expecting a decimal and you pass a string. – ricks Aug 18 '21 at 15:32
  • 1
    @ricks floating point numbers are binary, not decimal. There is no way to round to a specific number of decimals without changing the representation from binary. Using something like the DECIMAL type in many databases in one, but the most common reason to round is for presentation, so using a string is not unreasonable. If you round because of accounting rules you should start with a decimal representation and not a floating point. – Theo Aug 19 '21 at 12:36
  • @Theo Thanks i did not know that, for my use case i was writing a test for an accounting calculation with decimals and i wanted to compare the output (a price #.##). I guess i could have just used this and compared it to a string and it would have made no difference. – ricks Aug 19 '21 at 14:10
96

Float#round can take a parameter in Ruby 1.9, not in Ruby 1.8. JRuby defaults to 1.8, but it is capable of running in 1.9 mode.

Community
  • 1
  • 1
steenslag
  • 79,051
  • 16
  • 138
  • 171
  • 1
    I know it does not appear to be the intention of Sam to round the number for the purpose of presenting something like a currency, but be aware that using #round(precision) will not work as intended if you are trying to do this (3.round(2) #=> 3.0, not 3.00). To get this, check out the answer by Theo below. – jaredsmith May 19 '14 at 21:48
6

Edit

After getting feedback, It seems the original solution didn't work. That's why updated the answer as one of the suggestions.

def float_of_2_decimal(float_n) 
  float_n.to_d.round(2, :truncate).to_f
end

Other answers may work, if you want to have rounded numbers of 2 decimal places. But, If you want to have floating point numbers with first two decimal places without rounding, Those answers won't help.

So, to get a floating point number with first two decimal places, I used this technique. Doesn't work in some cases

def float_of_2_decimal(float_n)
  float_n.round(3).to_s[0..3].to_f
end

with 5.666666666666666666666666, it will return 5.66 instead of rounded 5.67. Hope it will help someone

Community
  • 1
  • 1
Anwar
  • 1,755
  • 1
  • 21
  • 32
  • 1
    This doesn't work. In order to get it to work you need to account for any size number. Using the pattern implemented here you can: `def float_of_2_decimal(float_n) num = float_n.to_s.split('.') num[1] = num[1][0..1] num.join(".").to_f end` Or much simpler you can use `float_n.to_d.round(2, :truncate).to_f` – rorykoehler Apr 06 '16 at 04:15
  • Anything with a int bigger than 9 before the decimal place – rorykoehler Apr 06 '16 at 04:20
  • Thank you for the point. But, your suggested methods fail on big numbers too! – Anwar Apr 06 '16 at 04:55
  • For `11111111111111111.222222222222222` as input, first one shows `1.11` and second one shows `1.11111111111111e+16` – Anwar Apr 06 '16 at 05:12
  • 1
    Yes you are right ... once 16 places in front or over. Overflow issue. Best stick to big decimal if working with large numbers. Typecasting introduces problem – rorykoehler Apr 06 '16 at 05:17
  • @rorykoehler I've found another case, where my solution failed. That's why edited the answer. – Anwar Apr 06 '16 at 18:09
  • `float_n.to_d.round(2, :truncate).to_f` is a much better solution as it deals with very large numbers correctly. You should use that. – rorykoehler Apr 07 '16 at 06:48
  • 1
    @rorykoehler I tried your way and got: `'111111111111111111111111.222222'.to_d.round(2, :truncate).to_f` returns `1.1111111111111111e+23`. But it works if you remove the last `.to_f` – lacostenycoder Jan 05 '20 at 11:01
-7

Try this:

module Util
module MyUtil



    def self.redondear_up(suma,cantidad, decimales=0)

        unless suma.present?
            return nil
        end


        if suma>0
            resultado= (suma.to_f/cantidad)
            return resultado.round(decimales)
        end


        return nil


    end

end 
end 
HalleyRios
  • 602
  • 1
  • 4
  • 18
  • 3
    Thanks for answering. Could you please revise it to be in English, as the question was asked in English. – Jared Sep 29 '16 at 18:08
-18

to truncate a decimal I've used the follow code:

<th><%#= sprintf("%0.01f",prom/total) %><!--1dec,aprox-->
    <% if prom == 0 or total == 0 %>
        N.E.
    <% else %>
        <%= Integer((prom/total).to_d*10)*0.1 %><!--1decimal,truncado-->
    <% end %>
        <%#= prom/total %>
</th>

If you want to truncate to 2 decimals, you should use Integr(a*100)*0.01

Ernest
  • 8,701
  • 5
  • 40
  • 51
  • 5
    No one should do this EVER when casting percentages. This is really bad form because by truncating you loose the ability to properly ROUND to the nearest 2 decimal positions. ie 0.455 if you just truncate you get 0.45 which is wrong for rounding because it should result in 0.46 . Never truncate a decimal always round the number else the result will be wrong when rounding up must ocurr. – The Gugaru Aug 26 '15 at 20:27