2009-09-08 11 views
2
sub is_integer { 
    defined $_[0] && $_[0] =~ /^[+-]?\d+$/; 
} 

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

上記のコードでは、入力を999999999999999999999999999999999999999999とすると、出力は実数ではなくなります。999 ... 9はPerlで実数ですか?

なぜそれはそのような振る舞いですか?

は、私は1つのより多くの事を言及するのを忘れてしまった:

私は上記の値として$xためにこのコードを使用していた場合:

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

出力がrealです。

これはどのように可能ですか?

答えて

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

つまり、Perlはこの数字に科学表現を使用しているため、正規表現が一致しません。

3

もう1つ追加するだけです。他の人が説明したように、作業している数はPerl整数の範囲外です(140ビットマシンでない限り)。したがって、変数は浮動小数点数として格納されます。正規表現は文字列で動作します。したがって、正規表現が操作される前に数値が文字列表現に変換されます。

7

Scalar::Util(コアモジュール)のlooks_like_number機能を使用してください。

use Scalar::Util qw(looks_like_number); 

say "Number" if looks_like_number 999999999999999999999999999999999999999999; 

# above prints "Number" 
+0

Scalar :: Utilモジュールを共有できますか? –

+0

cpan Scalar :: Util – kixx

+4

Scalar :: UtilはPerlのコアモジュールです – draegtun

1

また、bignumをPerlのドキュメントでご覧ください。

2

何が起きているのか他の人は説明しました。箱から出て、Perlは科学的表記を使わずに大きな数字を扱うことができません。

大きな数字を扱う必要がある場合は、Math::BigIntなどのbignumまたはそのコンポーネントを参照してください。例:

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+$/; 
}