Uno
Uno

Reputation: 21

How to check if a string is an Integer or Float

I want to check if my variable is either an integer or float. This is for a calculator. I don't want it to be looping indefinitely.

How would I do so? I tried to do the following:

puts "Enter a number: "
num1 = gets.chomp()
while !(num1 == Integer.superclass or num1 == Float.superclass)
  puts "Enter an actual number: "
  num1 = gets.chomp()
end

Upvotes: 1

Views: 11937

Answers (4)

user16452228
user16452228

Reputation:

This question wasn't explicitly asked, but if the code is "for a calculator" as stated, I would ask myself what types of numbers are valid. Here are just a few scenarios to consider:

num1 = ".1"
num1 = "1."
num1 = "_0"
num1 = "0_"
num1 = "1_0"
num1 = "1_000"
num1 = "1e+5"
num1 = "1+1"
num1 = "1 % 2"
num1 = "3**2"
num1 = "(0)"
num1 = "2(2-1)"

Some of the above are valid floats or integers as far as Ruby is concerned but possibly shouldn't be for your purposes, and some are NOT valid in Ruby but arguably should be considered valid depending on the ultimate purpose and behavior of your code. Assuming you're just wanting to roughly match Ruby's definitions though, I think the most dependable method is the to use the Float(string) approach like so:

Float(num1) rescue <do_something>

This approach will only convert a string if the string is a valid float or integer (with the exception of allowing for a leading decimal); otherwise, it will throw an error which would then need to be rescued one way or another. Under tho hood, I believe Ruby just runs a pre-configured regex string match. This approach can be a bit slower to execute because of the time it takes to run the string match and because of the error handling. In addition it does allow for a leading decimal, exponent annotation, and non leading/trailing underscores which may or may not be desirable..

The alternatives on the other hand almost all require first converting your string to a float or integer which has all sorts of problems. Using my potentially problematic examples above for instance:

  • Every one will successfully convert to a valid float.
  • Every one will successfully convert to a valid integer

In addition:

  • Strings with trailing non-numeric characters will successfully convert to either a float or an integer using the leading numeric value meaning "7 hundred" #=> 7.0 or 7
  • Floats with trailing zeros will result in the trailing zeros being dropped meaning that testing for equality will miss these instances since "5.2" == "5.20" #=> false

The various pitfalls required for conversion from string to numeric make any non-regex, non-Float(string), or non-Integer(string) solution pretty difficult to implement in a dependable way.

Upvotes: 0

Pallav Kabra
Pallav Kabra

Reputation: 458

If you want to check if a variable is of certain type, you can simply use kind_of?:

1.kind_of? Integer # true
1.5.kind_of? Float # true

Upvotes: 5

iGian
iGian

Reputation: 11193

In general, one option:

10.class == Integer # => true
10.5.class == Float # => true

Or, another:

10.is_a? Integer # => true
10.5.is_a? Float # => true

But since the input is a string, this can be a possible solution to check if a string is an integer or a float number, monkey patching the String class:

module StringFloatOrInteger
  def integer_or_float?
   begin !!Float(self) rescue false end
  end

  def integer_not_float?
    begin !!Integer(self) rescue false end  
  end

  def integer?
    integer_not_float? & integer_or_float?
  end

  def float?
    !integer_not_float? & integer_or_float?
  end
end

String.include StringFloatOrInteger

"home".integer? # => false
"home".float? # => false
"10".integer? # => true
"10".float? # => false
"10.5".integer? # => false
"10.5".float? # => true

In your case, you can use like this, asking n times for the input

def get_integer
  2.times do # or whatever times
    puts "Please enter an integer: "
    input = gets.chomp
    return input.to_i if input.integer?
  end
  return nil # or whatever
end

number = get_integer

Upvotes: 2

dkulkarni
dkulkarni

Reputation: 2830

Since the input is a string, you will need to first convert them to an integer or float

So if you do the following and the input is "hello", it would return 0.0

num1 = gets.chomp.to_f

If you would like to validate strictly if it is an integer, then you can do so by

input = gets.chomp
until input.is_a?(Fixnum) do
 print "Please enter a number: "
 input = Integer(gets.chomp) rescue nil
end

Upvotes: 1

Related Questions