Sonny Black
Sonny Black

Reputation: 1617

How to calculate percentages with rounding

I have the following code:

def self.percent
  (Order.revenue.to_f / Order.goal.to_f) * 100.to_f
end

And the output is hideous:

0.47939999999999994% Funded

  1. How can I make it so that it doesn't have the 0 in front i.e. 0.1.., and only starts calculating at 1%, 2%, ...?

  2. How do I get rid of the 0.43234324? I'd like it to display nice round numbers i.e. 1%, 2%, and so on.

Upvotes: 0

Views: 7112

Answers (3)

Sudhir Vishwakarma
Sudhir Vishwakarma

Reputation: 805

You need to find the difference between the original number/price and the new number /price. And divide it by the original number/ price to get the percentage:

def percentage_off
   (Float(original_price - our_price) / original_price * 100).ceil
end

the input example would now return (1000 - 900) / 1000 * 100 = 10

Upvotes: 0

Wayne Conrad
Wayne Conrad

Reputation: 107989

It's not always necessary to round the number. Often it's sufficient to simply output it with only the precision you want. The method String#%, which is a thin wrapper around Kernel#sprintf, works well for this.

Examples:

"%.0f" % 0.47939999999999994    # => "0"

The "%.0f" specification means to print a float point number with zero digits after the decimal point.

This method uses 5/4 rounding, which is fine for many applications. Here we can see that the number is rounded up:

"%.0f" % 23.6    # => "24"

Upvotes: 0

Guilherme Franco
Guilherme Franco

Reputation: 1483

OK, I think we can separate two answers here. First of all, you have to pay attention with rounding and truncating values. It could be dangerous in terms of inconsistent information. Anyways, based on your case, here it is.

  • If you want to display only integers and ignore the decimal part of the number, you can use either ceil or floor

    0.47939999999999994.ceil 
    #=> 1
    
    0.47939999999999994.floor 
    #=> 0
    
  • If you want to round your decimal, you can use round passing the precision desired:

    0.47939999999999994.round
    #=> 0
    
    0.47939999999999994.round(1)
    #=> 0.5
    
    0.47939999999999994.round(2) 
    #=> 0.48
    
    0.47939999999999994.round(3)
    #=> 0.479
    
    0.47939999999999994.round(4)
    #=> 0.4794
    

Your method should look like the following (using round)

def self.percent
  ((Order.revenue.to_f.round(2) / Order.goal.to_f.round(2)) * 100).round(2)
end

I hope it helps !

Upvotes: 5

Related Questions