Is 999 ... 9 a real number in Perl?

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

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

      

For the code mentioned above, if we specify the input as 999999999999999999999999999999999999999999

, it gives the output as not a valid number.

Why is he behaving this way?

I forgot to mention one more thing:

If I use this code for $x

as above value:

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

      

Conclusion real

.

How is this possible?

+2


source to share


5 answers


$ perl -e 'print 999999999999999999999999999999999999999999'
1e+42

      



i.e. Perl uses scientific notation for this number and therefore your regex does not match.

+10


source


Use a function looks_like_number

from Scalar :: Util (which is the main module).



use Scalar::Util qw( looks_like_number );

say "Number" if looks_like_number 999999999999999999999999999999999999999999;

# above prints "Number"

      

+7


source


Just 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). Hence the variable will be stored as a floating point number. Regular expressions act on strings. Therefore, the number is converted to its string representation before being acted upon by the regular expression.

+3


source


Others explained what was happening: Out of the box, Perl cannot handle numbers large without using scientific notation.

If you need to work with large numbers, check out 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+$/;
}

      

+2


source


Alternatively, you can take a look at bignum in the Perl documentation.

+1


source







All Articles