tags:

views:

233

answers:

5
sub is_integer {
   defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}

sub is_float {
   defined $_[0] && $_[0] =~ /^[+-]?\d+(\.\d+)?$/;
}

For the code mentioned above, if we give input as 999999999999999999999999999999999999999999, it is giving output as not real number.

Can anyone help me in this regard why it is behaving like that?

I forgot to mention one more thing :

if i am using this code for $x as above value

if($x > 0 || $x <= 0 ) { print "Real"; }

output is real.

how is it possible? can anyone explain???

+7  A: 
$ perl -e 'print 999999999999999999999999999999999999999999'
1e+42

i.e. Perl uses scientific representation for this number and that is why your regexp doesn't match.

Michał Górny
+3  A: 

Just to add one more thing. As others have explained, the number you are working with is out of range for a Perl integer (unless you are on a 140 bit machine). Therefore, the variable will be stored as a floating point number. Regular expressions operate on strings. Therefore, the number is converted to its string representation before the regular expression operates on it.

Nic Gibson
+6  A: 

Have a look at using looks_like_number function from Scalar::Util (a core module).

use Scalar::Util qw( looks_like_number );

say "Number" if looks_like_number 999999999999999999999999999999999999999999;

# above prints "Number"

/I3az/

draegtun
can you please share Scalar :: Util module ???
cpan Scalar::Util
kixx
Scalar::Util is a core module so it comes with Perl
draegtun
Meaning the 'use' command above will work without installing anything. However, if it objects to 'say', use 'print' instead ('say' is a bit modern and doesn't work in Perl 5.8).
ijw
+1  A: 

Also, you may want to take a look at bignum in the Perl documentation.

Leonardo Herrera
+2  A: 

Others have explained what is going on: out of the box, Perl can't handle numbers that large without using scientific notation.

If you need to work with large numbers, take a look at bignum or its components, such as Math::BigInt. For example:

use strict;
use warnings;
use Math::BigInt;

my $big_str = '900000000000000000000000000000000000000';
my $big_num = Math::BigInt->new($big_str);

$big_num ++;
print "Is integer: $big_num\n" if is_integer($big_num);

sub is_integer {
   defined $_[0] && $_[0] =~ /^[+-]?\d+$/;
}
FM