Reputation: 643
I'm trying to find the decimal value from a percentage that a user inputs.
For example, if a user inputs "15", i will need to do a calculation of 0.15 * number
.
I've tried using .to_f
, but it returns 15.0
:
15.to_f
#=> 15.0
I also tried to add 0.
to the beginning of the percentage, but it just returns 0
:
15.to_s.rjust(4, "0.").to_i
#=> 0
Upvotes: 0
Views: 482
Reputation: 114158
I'm trying to find the amount from a percentage that a user inputs
If you retrieve the input via gets
, you typically convert it to a numeric value first, e.g.
percentage = gets.to_i
#=> 15
Ruby is not aware that this 15
is a percentage. And since there's no Percentage
class, you have to convert it into one of the existing numeric classes.
15% is equal to the fraction 15/100, the ratio 15:100, or the decimal number 0.15.
If you want the number as a (maybe inexact) Float
, you can divide it by 100
via fdiv
:
15.fdiv(100)
#=> 0.15
If you prefer a Rational
you can use quo
: (it might also return an Integer
)
15.quo(100)
#=> (3/20)
Or maybe BigDecimal
for an arbitrary-precision decimal number:
require 'bigdecimal'
BigDecimal(15) / 100
#=> 0.15e0
BigDecimal
also accepts strings, so you could pass the input without prior conversion:
input = gets
BigDecimal(input) / 100
#=> 0.15e0
Upvotes: 0
Reputation: 84343
100.0
The easiest way to do what you're trying to do is to divide your input value by a Float (keeping in mind the inherent inaccuracy of floating point values). For example:
percentage = 15
percentage / 100.0
#=> 0.15
One benefit of this approach (among others) is that it can handle fractional percentages just as easily. Consider:
percentage = 15.6
percentage / 100.0
#=> 0.156
If floating point precision isn't sufficient for your use case, then you should consider using Rational or BigDecimal numbers instead of a Float. Your mileage will very much depend on your semantic intent and accuracy requirements.
Make sure you have ahold of a valid Integer in the first place. While others might steer you towards String#to_i, a more robust validation is to use Kernel#Integer so that an exception will be raised if the value can't be coerced into a valid Integer. For example:
print "Enter integer: "
percentage = Integer gets
If you enter 15\n
then:
percentage.class
#=> Integer
If you enter something that can't be coerced to an Integer, like foo\n
, then:
ArgumentError (invalid value for Integer(): "foo\n")
Using String#to_i is much more permissive, and can return 0
when you aren't expecting it, such as when called on nil, an empty string, or alphanumeric values that don't start with an integer. It has other interesting edge cases as well, so it's not always the best option for validating input.
Upvotes: 1