Check numbers

Hello people,

how to check string to know if it is number or not.

ex:
isnumber(‘text’) ==> false
isnumber(‘22’) ==> true

Thanks.

There are a few ways to do this. I’ll give some examples for checking
if the string is an integer, which might be sufficient for you.
Checking for floats, rationals, etc will be more complex.

is_integer.rb

class String
def is_integer?
!self.empty? && self =~ /\A\d+\Z/ # not the empty string and
containing only one or more digits
end

def is_integer2?
!self.empty? && Integer(self) rescue false # not the empty string
and capable of being coerced by Integer()
end

def is_integer3?
!self.empty? && self.scan(/\D/).empty? # not the empty string and
containing no non-digit characters
end
end

Here is one benchmark:

["", “1”, “123”, “foo”, “foo123”].each { |string| string.is_integer?}

(n = 10,000)

            user     system      total        real
regex:  0.070000   0.000000   0.070000 (  0.065365)

Integer(): 0.580000 0.040000 0.620000 ( 0.620194)
scan: 0.150000 0.000000 0.150000 ( 0.150243)

Using Integer and rescuing the thrown exception is quick for integer
strings but grossly inefficient for non-integer strings (as expected).
The regex is fastest all-around of the three examples given and
benchmarking shows that short-circuiting on the empty string really
speeds up the special case of “”.is_integer?

Feel free to suggest other implementations. I’ll put the lib, unit
test and benchmark files on my blog for you to use. (As soon as I get
my blog up and running. Probably tomorrow. Stay tuned.) Until then,
here’s the benchmark used above:

is_integer_bm.rb

require ‘benchmark’
require ‘is_integer’ # your is_integer.rb where the extension to
String is located

STRINGS = ["", “1”, “123”, “foo”, “foo123”]

def bench_total
n = 10000
puts “\n”
print STRINGS.inspect
print".each { |string| string.is_integer?}"
print " # (n = 10,000)\n"
Benchmark.bm(10) do |x|
x.report(" regex:") { n.times { STRINGS.each{ |str|
str.is_integer? } } }
x.report(“Integer():”) { n.times { STRINGS.each{ |str|
str.is_integer2? } } }
x.report(" scan:") { n.times { STRINGS.each{ |str|
str.is_integer3? } } }
end
end

bench_total

Rein

faisal,

The ternary here is useless as == already returns a boolean, and this
is also integer only rather than any number, so changing your method
to:

class String
def is_integer?
self.to_i.to_s == self
end
end

and adding it to the benchmark, we get:

["", “1”, “123”, “foo”, “foo123”].each { |string| string.is_integer?}

(n = 10,000)

            user     system      total        real
regex:  0.070000   0.000000   0.070000 (  0.069953)

Integer(): 0.580000 0.040000 0.620000 ( 0.635358)
scan: 0.150000 0.000000 0.150000 ( 0.172896)
to_i.to_s: 0.150000 0.000000 0.150000 ( 0.157933)

Or roughly equal to the scan method but still about half as fast as
the regex. So far you’re in second place. Thanks for playing :wink:

Incidentally faisal’s method does actually work as a test for integer-
ness. (There has to be a better word…) My only issue with it is that
it is not very intention revealing. Then again, neither is the regex
if you aren’t familiar with regexen.

Incidentally, the regex method without the check for empty? is
actually slightly faster overall than with the check for empty? so the
most performant method so far is:

class String
def is_integer?
self =~ /\A\d+\Z/
end
end

def isnumber(string)
string.to_i.to_s == string ? true : false
end

-faisal

rewritten in a object oriented manner:

class String
def is_integer?
self.to_i >= 1
end
end

“0”.is_integer? #=> false
“-123”.is_integer? #=> false

'fraid not.

You did, however, remind me about negative integers.

class String
def is_integer?
self =~ /\A-?\d+\Z/
end
end

and the scan method won’t work on negative integers. Whoops!

On Sep 3, 2:09 am, Jamal S. [email protected]

For posterity: http://reinh.com/2007/9/4/string-is_integer

Rein

On Sep 3, 2007, at 2:17 AM, [email protected] wrote:

The ternary here is useless as == already returns a boolean

i could argue that it’s mostly for readability, although having used
a ternary in the first place i could argue that i should have an
entire chorus lined up to laugh at the code.

-faisal

Well, I would do this as follow in PHP

@num = @as.to_i

if @num >= 1
puts “is number”
end

Would this work?