Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

How to determine if something is numeric?

by mifflin (Curate)
on Jan 30, 2004 at 19:13 UTC ( #325341=perlquestion: print w/replies, xml ) Need Help??

mifflin has asked for the wisdom of the Perl Monks concerning the following question:

I need to determine if something is numeric.
By numeric I mean...
1. no alpha
2. no leading zeros ( 0001 or -0001 needs to be considered not-numeric)

here is what I came up with
use warnings; use strict; my $var = 'abc'; no warnings; my $testvar = $var + 0; use warnings; if ($var eq $testvar) { print "$var is numeric\n"; } else { print "oops, $var is NOT numeric\n"; }
Is this considered the right way to go about it? Is there a better way?

Replies are listed 'Best First'.
Re: How to determine if something is numeric?
by Ovid (Cardinal) on Jan 30, 2004 at 19:19 UTC

    If I've understood your specs correctly:

    use Scalar::Util 'looks_like_number'; if (0 != substr($var,0,1) and looks_like_number($var)) { # it's a number }

    Update: As sporty pointed out below, this breaks on negative numbers. I didn't see that dash in your post. Here's the fix:

    use Scalar::Util 'looks_like_number'; if ($var !~ /^-?0/ && looks_like_number($var)) { # it's a number }

    Cheers,
    Ovid

    New address of my CGI Course.

      we must have different versions of something.
      when I run that code id get the following error

      erickn@hestia:/home/erickn/wo> perl x "looks_like_number" is not exported by the Scalar::Util module Can't continue after import errors at x line 5 BEGIN failed--compilation aborted at x line 5.

      line 5 is the use line

      I'm using perl 5.8.0
      It looks like Scalar::Util uses List::Util and that version in my system is 1.07_00
      any ideas?
        mifflin,
        looks_like_number was introduced in version 1.10 of Scalar::Util. The sub looks like this:
        sub looks_like_number { local $_ = shift; # checks from perlfaq4 return 1 unless defined; return 1 if (/^[+-]?\d+$/); # is a +/- integer return 1 if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/); # +a C float return 1 if ($] >= 5.008 and /^(Inf(inity)?|NaN)$/i) or ($] >= 5.006 +001 and /^Inf$/i); 0; }
        As I stated in my reply - I do not think this meets your requirements because it also handles decimals, scientific notation, NaN, and Inf.

        Cheers - L~R

        It looks like Scalar::Util uses List::Util and that version in my system is 1.07_00 any ideas?
        Upgrade :)

        MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
        I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
        ** The third rule of perl club is a statement of fact: pod is sexy.

      This breaks on negative numbers.

      Play that funky music white boy..
Re: How to determine if something is numeric?
by Limbic~Region (Chancellor) on Jan 30, 2004 at 19:28 UTC
    mifflin,
    You haven't done a very good job of explaining exactly what you mean by numeric. Are you only looking for integers or do decimals count? You say no alphas, but is a larger integer represented in scientific notation acceptable? What about Inf and NaN? I would suggest having a look at Scalar::Util's looks_like_number but that doesn't seem to be what you want.

    If you are looking for positive or negative whole integers that do not have any leading zeros, the following should work. Remember 0 by itself will not be numeric.

    #!/usr/bin/perl -w use strict; my $test = -413; print "$test is ok\n" if numeric( $test ); sub numeric { my $number = shift; return 0 if ! $number; my $first = substr( $number , 0 , 1 ); $number = substr($number, 1) if $first eq '-'; return 1 if $number =~ /^[1-9]\d+?$/; return 0; }
    Cheers - L~R
Re: How to determine if something is numeric?
by exussum0 (Vicar) on Jan 30, 2004 at 19:29 UTC
    All you have done is forced perl to do it's best to turn a string into a number. Try assigning var to 23g, 23 g 23.0g, and you'll see it just gets converted. The better question is, why don't you want the implicit conversion?

    Play that funky music white boy..
Re: How to determine if something is numeric?
by ysth (Canon) on Jan 30, 2004 at 19:38 UTC
    That actually looks pretty good. It will show non-numeric for leading/trailing spaces that perl will usually ignore. Only problem I can think of is that it may report non-numeric for something like "100000000000000000000" (because it will turn into 1e20).

    When deliberately ignoring a warning, I like to isolate it to the particular warning and operation involved, like:

    my $testvar = do {no warnings "numeric"; $var + 0};
Re: How to determine if something is numeric?
by Anonymous Monk on Jan 30, 2004 at 19:44 UTC
    #!/usr/bin/perl -w use strict; my @numbers = ('-1', 1, 1000, '0001', 'abc', 34, '0x65', "1.2", '3.', '.3'); sub is_numeric { return $_[0] =~ /^[1-9][0-9.]*$/ } for (@numbers) { if (is_numeric($_) ){ print "$_ is numeric\n"; } else { print "$_ is NOT numeric\n"; } } __END__ -1 is NOT numeric 1 is numeric 1000 is numeric 0001 is NOT numeric abc is NOT numeric 34 is numeric 0x65 is NOT numeric 1.2 is numeric 3. is numeric .3 is NOT numeric

      Try this @numbers:

      my @numbers = qw(0.001 1.001 192.168.0.1);

      antirice    
      The first rule of Perl club is - use Perl
      The
      ith rule of Perl club is - follow rule i - 1 for i > 1

Re: How to determine if something is numeric?
by kutsu (Priest) on Jan 30, 2004 at 19:35 UTC

    Here's my take:

    die "$var non-numeric" if $var =~ /[^0-9]/; #dies if it starts with - $var =~ s/^0*//; #this will remove any leading zeros

    "Cogito cogito ergo cogito sum - I think that I think, therefore I think that I am." Ambrose Bierce

Re: How to determine if something is numeric?
by stefp (Vicar) on Jan 31, 2004 at 18:49 UTC
    If by numeric, you means a string that represents a natural integer in the decimal numeration system which first digit is not a zero, it happens to be a string $s that is left unchanged by the operation: $s+0

    print +($_+0 eq $_ ? ' ' : 'not '). "numeric: $_\n" for qw( 1 01 + a01 -3 -01 .1 ) numeric: 1 not numeric: 01 not numeric: a01 numeric: -3 not numeric: -01 not numeric: .1
    oops, I read you specif without reading the code. I came with the same solution as you.

    -- stefp

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://325341]
Approved by kutsu
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2021-03-06 08:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favorite kind of desktop background is:











    Results (116 votes). Check out past polls.

    Notices?