Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine if a string is a valid float value

Is there a way to simply check if a string value is a valid float value. Calling to_f on a string will convert it to 0.0 if it is not a numeric value. And using Float() raises an exception when it is passed an invalid float string which is closer to what I want, but I don't want to handle catching exceptions. What I really want is a method such as nan? which does exist in the Float class, but that doesn't help because a non-numeric string cannot be converted to a float without being changed to 0.0 (using to_f).

"a".to_f => 0.0  "a".to_f.nan? => false  Float("a") => ArgumentError: invalid value for Float(): "a" 

Is there a simple solution for this or do I need to write code to check if a string is a valid float value?

like image 327
Ben5e Avatar asked Jun 23 '09 18:06

Ben5e


People also ask

How do you check if a string contains a valid integer or float?

To check if a string is an integer or a float:Use the str. isdigit() method to check if every character in the string is a digit. If the method returns True , the string is an integer. If the method returns False , the string is a floating-point number.

How do you check if a string is a valid float in Java?

To check if a string is a valid Float, use the Float. parseFloat() method, with the string to be checked passed as a parameter.

How do you check if a value is float or not?

Check if the value has a type of number and is not an integer. Check if the value is not NaN . If a value is a number, is not NaN and is not an integer, then it's a float.


2 Answers

Here's one way:

class String   def valid_float?     # The double negation turns this into an actual boolean true - if you're      # okay with "truthy" values (like 0.0), you can remove it.     !!Float(self) rescue false   end end  "a".valid_float? #false "2.4".valid_float? #true 

If you want to avoid the monkey-patch of String, you could always make this a class method of some module you control, of course:

module MyUtils   def self.valid_float?(str)     !!Float(str) rescue false   end end MyUtils.valid_float?("a") #false 
like image 67
Greg Campbell Avatar answered Oct 13 '22 08:10

Greg Campbell


An interesting fact about the Ruby world is the existence of the Rubinius project, which implements Ruby and its standard library mostly in pure Ruby. As a result, they have a pure Ruby implementation of Kernel#Float, which looks like:

def Float(obj)   raise TypeError, "can't convert nil into Float" if obj.nil?    if obj.is_a?(String)     if obj !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/       raise ArgumentError, "invalid value for Float(): #{obj.inspect}"     end   end    Type.coerce_to(obj, Float, :to_f) end 

This provides you with a regular expression that matches the internal work Ruby does when it runs Float(), but without the exception. So you could now do:

class String   def nan?     self !~ /^\s*[+-]?((\d+_?)*\d+(\.(\d+_?)*\d+)?|\.(\d+_?)*\d+)(\s*|([eE][+-]?(\d+_?)*\d+)\s*)$/   end end 

The nice thing about this solution is that since Rubinius runs, and passes RubySpec, you know this regex handles the edge-cases that Ruby itself handles, and you can call to_f on the String without any fear!

like image 22
Yehuda Katz Avatar answered Oct 13 '22 09:10

Yehuda Katz