<p>Is there a simple way in Perl that will allow me to determine if a given variable is numeric?  Something along the lines of:</p>

<pre><code>if (is_number($x))
{ ... }
</code></pre>

<p>would be ideal.  A technique that won't throw warnings when the <code>-w</code> switch is being used is certainly preferred.</p>

[{'answer_id': 12654, 'author': 'farmerchris', 'author_id': 1317, 'author_profile': 'https://Stackoverflow.com/users/1317', 'pm_score': 2, 'selected': False, 'text': '<p>Not perfect, but you can use a regex:</p>\n\n<pre><code>sub isnumber \n{\n    shift =~ /^-?\\d+\\.?\\d*$/;\n}\n</code></pre>\n'}, {'answer_id': 12667, 'author': 'andrewrk', 'author_id': 432, 'author_profile': 'https://Stackoverflow.com/users/432', 'pm_score': 4, 'selected': False, 'text': '<p>Usually number validation is done with regular expressions. This code will determine if something is numeric as well as check for undefined variables as to not throw warnings:</p>\n\n<pre><code>sub is_integer {\n   defined $_[0] &amp;&amp; $_[0] =~ /^[+-]?\\d+$/;\n}\n\nsub is_float {\n   defined $_[0] &amp;&amp; $_[0] =~ /^[+-]?\\d+(\\.\\d+)?$/;\n}\n</code></pre>\n\n<p>Here\'s some <a href="http://www.perl.com/doc/FMTEYEWTK/is_numeric.html" rel="noreferrer">reading material</a> you should look at.</p>\n'}, {'answer_id': 12736, 'author': 'Jon Ericson', 'author_id': 1438, 'author_profile': 'https://Stackoverflow.com/users/1438', 'pm_score': 2, 'selected': False, 'text': '<p>A slightly more robust regex can be found in <a href="http://search.cpan.org/dist/Regexp-Common" rel="nofollow noreferrer">Regexp::Common</a>.</p>\n\n<p>It sounds like you want to know if Perl thinks a variable is numeric.  Here\'s a function that  traps that warning:</p>\n\n<pre><code>sub is_number{\n  my $n = shift;\n  my $ret = 1;\n  $SIG{"__WARN__"} = sub {$ret = 0};\n  eval { my $x = $n + 1 };\n  return $ret\n}\n</code></pre>\n\n<p>Another option is to turn off the warning locally:</p>\n\n<pre><code>{\n  no warnings "numeric"; # Ignore "isn\'t numeric" warning\n  ...                    # Use a variable that might not be numeric\n}\n</code></pre>\n\n<p>Note that non-numeric variables will be silently converted to 0, which is probably what you wanted anyway.</p>\n'}, {'answer_id': 12742, 'author': 'naumcho', 'author_id': 779, 'author_profile': 'https://Stackoverflow.com/users/779', 'pm_score': 5, 'selected': False, 'text': '<p>Check out the CPAN module <a href="http://search.cpan.org/dist/Regexp-Common" rel="noreferrer">Regexp::Common</a>. I think it does exactly what you need and handles all the edge cases (e.g. real numbers, scientific notation, etc). e.g.</p>\n\n<pre><code>use Regexp::Common;\nif ($var =~ /$RE{num}{real}/) { print q{a number}; }\n</code></pre>\n'}, {'answer_id': 28589, 'author': 'nohat', 'author_id': 3101, 'author_profile': 'https://Stackoverflow.com/users/3101', 'pm_score': 8, 'selected': True, 'text': '<p>Use <code>Scalar::Util::looks_like_number()</code> which uses the internal Perl C API\'s looks_like_number() function, which is probably the most efficient way to do this.\nNote that the strings "inf" and "infinity" are treated as numbers.</p>\n\n<h2>Example:</h2>\n\n<pre><code>#!/usr/bin/perl\n\nuse warnings;\nuse strict;\n\nuse Scalar::Util qw(looks_like_number);\n\nmy @exprs = qw(1 5.25 0.001 1.3e8 foo bar 1dd inf infinity);\n\nforeach my $expr (@exprs) {\n    print "$expr is", looks_like_number($expr) ? \'\' : \' not\', " a number\\n";\n}\n</code></pre>\n\n<p>Gives this output:</p>\n\n<pre><code>1 is a number\n5.25 is a number\n0.001 is a number\n1.3e8 is a number\nfoo is not a number\nbar is not a number\n1dd is not a number\ninf is a number\ninfinity is a number\n</code></pre>\n\n<h2>See also:</h2>\n\n<ul>\n<li><a href="http://perldoc.perl.org/Scalar/Util.html" rel="noreferrer">perldoc Scalar::Util</a></li>\n<li><a href="http://perldoc.perl.org/perlapi.html#SV-Body-Allocation" rel="noreferrer">perldoc perlapi</a> for <code>looks_like_number</code></li>\n</ul>\n'}, {'answer_id': 3806159, 'author': 'ysth', 'author_id': 17389, 'author_profile': 'https://Stackoverflow.com/users/17389', 'pm_score': 5, 'selected': False, 'text': '<p>The original question was how to tell if a variable was numeric, not if it "has a numeric value".</p>\n\n<p>There are a few operators that have separate modes of operation for numeric and string operands, where "numeric" means anything that was originally a number or was ever used in a numeric context (e.g. in <code>$x = "123"; 0+$x</code>, before the addition, <code>$x</code> is a string, afterwards it is considered numeric).</p>\n\n<p>One way to tell is this:</p>\n\n<pre><code>if ( length( do { no warnings "numeric"; $x &amp; "" } ) ) {\n    print "$x is numeric\\n";\n}\n</code></pre>\n\n<p>If the bitwise feature is enabled, that makes <code>&amp;</code> only a numeric operator and adds a separate string <code>&amp;.</code> operator, you must disable it:</p>\n\n<pre><code>if ( length( do { no if $] &gt;= 5.022, "feature", "bitwise"; no warnings "numeric"; $x &amp; "" } ) ) {\n    print "$x is numeric\\n";\n}\n</code></pre>\n\n<p>(bitwise is available in perl 5.022 and above, and enabled by default if you <code>use 5.028;</code> or above.)</p>\n'}, {'answer_id': 4412308, 'author': 'fringd', 'author_id': 284511, 'author_profile': 'https://Stackoverflow.com/users/284511', 'pm_score': 2, 'selected': False, 'text': '<p>rexep not perfect... this is:</p>\n\n<pre><code>use Try::Tiny;\n\nsub is_numeric {\n  my ($x) = @_;\n  my $numeric = 1;\n  try {\n    use warnings FATAL =&gt; qw/numeric/;\n    0 + $x;\n  }\n  catch {\n    $numeric = 0;\n  };\n  return $numeric;\n}\n</code></pre>\n'}, {'answer_id': 12937508, 'author': 'Peter Vanroose', 'author_id': 1753621, 'author_profile': 'https://Stackoverflow.com/users/1753621', 'pm_score': 3, 'selected': False, 'text': '<p>A simple (and maybe simplistic) answer to the question <em>is the content of <code>$x</code> numeric</em> is the following:</p>\n\n<pre><code>if ($x  eq  $x+0) { .... }\n</code></pre>\n\n<p>It does a textual comparison of the original <code>$x</code> with the <code>$x</code> converted to a numeric value.</p>\n'}, {'answer_id': 16861447, 'author': 'CDC', 'author_id': 2441129, 'author_profile': 'https://Stackoverflow.com/users/2441129', 'pm_score': 1, 'selected': False, 'text': '<p>Try this:</p>\n\n<pre><code>If (($x !~ /\\D/) &amp;&amp; ($x ne "")) { ... }\n</code></pre>\n'}, {'answer_id': 18934806, 'author': 'Jason Van Patten', 'author_id': 2802457, 'author_profile': 'https://Stackoverflow.com/users/2802457', 'pm_score': -1, 'selected': False, 'text': "<p>if ( defined $x &amp;&amp; $x !~ m/\\D/ ) {}\nor\n$x = 0 if ! $x;\nif ( $x !~ m/\\D/) {}</p>\n\n<p>This is a slight variation on Veekay's answer but let me explain my reasoning for the change.</p>\n\n<p>Performing a regex on an undefined value will cause error spew and will cause the code to exit in many if not most environments. Testing if the value is defined or setting a default case like i did in the alternative example before running the expression will, at a minimum, save your error log.</p>\n"}, {'answer_id': 32889849, 'author': 'Swadhikar', 'author_id': 5397845, 'author_profile': 'https://Stackoverflow.com/users/5397845', 'pm_score': 1, 'selected': False, 'text': '<p>I found this interesting though</p>\n\n<pre><code>if ( $value + 0 eq $value) {\n    # A number\n    push @args, $value;\n} else {\n    # A string\n    push @args, "\'$value\'";\n}\n</code></pre>\n'}, {'answer_id': 34547363, 'author': 'zagrimsan', 'author_id': 2745865, 'author_profile': 'https://Stackoverflow.com/users/2745865', 'pm_score': 0, 'selected': False, 'text': '<p>Personally I think that the way to go is to rely on Perl\'s internal context to make the solution bullet-proof. A good regexp could match all the valid numeric values and none of the non-numeric ones (or vice versa), but as there is a way of employing the same logic the interpreter is using it should be safer to rely on that directly.</p>\n\n<p>As I tend to run my scripts with <code>-w</code>, I had to combine the idea of comparing the result of "value plus zero" to the original value with the <code>no warnings</code> based approach of @ysth:</p>\n\n<pre><code>do { \n    no warnings "numeric";\n    if ($x + 0 ne $x) { return "not numeric"; } else { return "numeric"; }\n}\n</code></pre>\n'}, {'answer_id': 35657449, 'author': 'bLIGU', 'author_id': 4615814, 'author_profile': 'https://Stackoverflow.com/users/4615814', 'pm_score': 0, 'selected': False, 'text': '<p>You can use Regular Expressions to determine if $foo is a number (or not).</p>\n\n<p>Take a look here:\n<a href="http://perldoc.perl.org/perlfaq4.html#How-do-I-determine-whether-a-scalar-is-a-number%2fwhole%2finteger%2ffloat%3f" rel="nofollow">How do I determine whether a scalar is a number</a></p>\n'}, {'answer_id': 72480461, 'author': 'Kevin', 'author_id': 824897, 'author_profile': 'https://Stackoverflow.com/users/824897', 'pm_score': 0, 'selected': False, 'text': "<p>There is a highly upvoted accepted answer around using a library function, but it includes the caveat that &quot;inf&quot; and &quot;infinity&quot; are accepted as numbers.  I see some regex stuff for answers too, but they seem to have issues.  I tried my hand at writing some regex that would work better (I'm sorry it's long)...</p>\n<pre><code>/^0$|^[+-]?[1-9][0-9]*$|^[+-]?[1-9][0-9]*(\\.[0-9]+)?([eE]-?[1-9][0-9]*)?$|^[+-]?[0-9]?\\.[0-9]+$|^[+-]?[1-9][0-9]*\\.[0-9]+$/\n</code></pre>\n<p>That's really 5 patterns separated by &quot;or&quot;...</p>\n<p><strong>Zero:</strong> <code>^0$</code><br>\nIt's a kind of special case.  It's the only integer that can start with 0.</p>\n<p><strong>Integers:</strong> <code>^[+-]?[1-9][0-9]*$</code><br>\nThat makes sure the first digit is 1 to 9 and allows 0 to 9 for any of the following digits.</p>\n<p><strong>Scientific Numbers:</strong> <code>^[+-]?[1-9][0-9]*(\\.[0-9]+)?([eE]-?[1-9][0-9]*)?$</code><br>\nUses the same idea that the base number can't start with zero since in proper scientific notation you start with the highest significant bit (meaning the first number won't be zero).  However, my pattern allows for multiple digits left of the decimal point.  That's incorrect, but I've already spent too much time on this... you could replace the <code>[1-9][0-9]*</code> with just <code>[0-9]</code> to force a single digit before the decimal point and allow for zeroes.</p>\n<p><strong>Short Float Numbers:</strong> <code>^[+-]?[0-9]?\\.[0-9]+$</code><br>\nThis is like a zero integer.  It's special in that it can start with 0 if there is only one digit left of the decimal point.  It does overlap the next pattern though...</p>\n<p><strong>Long Float Numbers:</strong> <code>^[+-]?[1-9][0-9]*\\.[0-9]+$</code><br>\nThis handles most float numbers and allows more than one digit left of the decimal point while still enforcing that the higher number of digits can't start with 0.</p>\n<p><strong>The simple function...</strong><br></p>\n<pre><code>sub is_number {\n    my $testVal = shift;\n    return $testVal =~ /^0$|^[+-]?[1-9][0-9]*$|^[+-]?[1-9][0-9]*(\\.[0-9]+)?([eE]-?[1-9][0-9]*)?$|^[+-]?[0-9]?\\.[0-9]+$|^[+-]?[1-9][0-9]*\\.[0-9]+$/;\n}\n</code></pre>\n"}]
['https://Stackoverflow.com/questions/12647', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/872/']