在perl中,我想检查给定变量是否保持浮点数不是。要检查我正在使用,
my $Var = 0.02 # Floating point number
if (int($Var) != $Var) {
# floating point number
}
但上述代码不适用于0.0,
我怎样才能做到这一点?
答案 0 :(得分:15)
这是常见问题解答。见How do I determine whether a scalar is a number/whole/integer/float?
您也可以使用Scalar::Util::Numeric。
有趣的是,而
#!/usr/bin/perl
use strict; use warnings;
use Scalar::Util::Numeric qw(isint);
my $x = 0.0;
print "int\n" if isint $x;
打印int
(如果查看源代码,这并不奇怪),根据@ tchrist的注释,应该可以查看变量结构中提供的信息,以区分0
和{ {1}}:
0.0
输出:
SV = NV(0x18683cc) at 0x182c0fc REFCNT = 1 FLAGS = (PADMY,NOK,pNOK) NV = 0 SV = IV(0x182c198) at 0x182c19c REFCNT = 1 FLAGS = (PADMY,IOK,pIOK) IV = 0 SV = PVNV(0x397ac) at 0x182c19c REFCNT = 1 FLAGS = (PADMY,NOK,pNOK) IV = 0 NV = 0 PV = 0
在我看来,检查只需要查看是否设置了#!/usr/bin/perl
use strict; use warnings;
use Devel::Peek;
my $x = 0.0; print Dump $x;
my $y = 0; print Dump $y;
$y *= 1.1; print Dump $y;
标志。即使是最简单的XS也需要很长时间才能编写,因此我不会提供实现。
答案 1 :(得分:7)
($Var - int($Var))?'float':'int'
答案 2 :(得分:1)
您可以使用autobox :: universal module,它是autobox的一部分。
#! /usr/bin/perl
use autobox::universal qw(type);
my $x = 42;
print type($x), "\n";;
$x = 42.0;
print type($x), "\n";
输出:
INTEGER
FLOAT
答案 3 :(得分:0)
您必须通过精通正则表达式来处理自己的问题并处理极端情况,或者服从第三方库并捕获并抑制它们引发的异常。
sub does_this_variable_look_like_a_perl_float {
$number_of_arguments = 0 + @_;
#If you passed too many arguments, exit program, it's certainly not a float
if ($number_of_arguments != 1){
print "ArgumentException, you passed an incorrect number of parameters.\n";
return 0;
}
$variable = $_[0];
$first_argument = shift;
if ( ref(\$first_argument) eq 'ARRAY') {
#arrays are not floats
print("arrays are not floats");
return 0;
}
if ($variable =~ m/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/){
return 1;
}
return 0;
}
sub is_convertable_to_float__casting_and_killing_canaries {
$number_of_arguments = 0 + @_;
if ($number_of_arguments != 1){
print "ArgumentException, you passed an incorrect number of parameters.\n";
return 0;
}
my $result = 0;
$variable = $_[0];
use Error qw(:try);
try {
use Scalar::Util qw(blessed dualvar isdual readonly refaddr reftype
tainted weaken isweak isvstring looks_like_number
set_prototype);
$numeric_code = looks_like_number( $variable );
if ($numeric_code != 0){
$result = 1;
}
else{
$result = 0;
}
}
catch Error with { $result = 0; };
return $result;
}
sub is_float {
#Darkwing Duck says "I like Perl5's duck typing, so it's a float when I
#look at it with my regex goggles, and it overlays yes"
return does_this_variable_look_like_a_perl_float(@_);
#Beta-7 insists on a practical solution, the variable is a float when I ask
#a 3rd party library if it is a float, and the 3rd party classifies it
#as a float, without any major malfunctions or trapped bubble up implimentationitis.
#return is_convertable_to_float__casting_and_killing_canaries(@_);
}
#NO:
print(is_float("")); #blankstring
print(is_float("yeah")); #strings with ascii letters
print(is_float(" ")); #space whitespace
print(is_float("\t\n")); #tabs and newlines
print(is_float(" 58 ")); #whitespace on either side
print(is_float('e')); #e by itself
print(is_float('0xf')); #0x hexidecimal
print(is_float('\xf')); #\x hexidecimal
print(is_float("1,234.56")); #commas as thousands separator
print(is_float("35,5")); #European, East oriental comma
print(is_float(undef)); #undef and variants
print(is_float("NaN")); #nan and variants
print(is_float("inf")); #nan and variants
print(is_float("infinity")); #inf and variants
print(is_float("null")); #null and variants
print(is_float("12.34.56")); #double dots
print(is_float("四")); #unicode, oriental japanese 4
print(is_float("#56")); #Pound sign
print(is_float("56%")); #percent sign
print(is_float("56^3")); #arithmatic expressions not interpreted
print(is_float("+1e1.5")); #decimals in exponent
print(is_float("+-1")); #make up your mind
print("\n");
#YES:
print(is_float(35)); #bare integer
print(is_float(35.5)); #decimal numeric, typical float
print(is_float(35.00000)); #superfluous zeros to the right
print(is_float("35")); #bare integer packaged as string
print(is_float(0)); #integer zero
print(is_float(07)); #leading zero makes for octal
print(is_float(000)); #stealth octal zero
print(is_float(-13)); #negative numbers
print(is_float(12e2)); #integers with e scientific notation
print(is_float(12.2e2)); #float with scientific notation
print(is_float(12.E4)); #float with e after period and scientific notation
print(is_float(.4)); #mantissa only
print(is_float(6e7777777777777)); #huge number
print(is_float(1.797693e+308)); #max value
print(is_float("0E0")); #zero in exponential
print(is_float(0**0)); #exponentiation
print(is_float("-5e-5")); #raise a negative to a negative
print(is_float("+5e+5")); #raise a positive with plus to a positive
print(is_float(0xfade)); #valid hexidecimal converted before pass by value
print(is_float(0b1100_0000)); #valid binary converted before pass by value
print("\n");
#ERROR:
print(is_float(5,6,7))
my @s = (10,20,30);
print(is_float(@s));
$arr = (5, 'foo', 7);
print(is_float($arr)); #an array containing integers and strings
print(is_float((1, 2, 3))); #error, array is not float
print(is_float(35,5)); #error, comma is not a decimal here, that's 2 parameters
“ does_this_variable_look_like_a_perl_float()的结果:
0000000000000000000000
11111111111111111111
“ is_convertable_to_float__casting_and_killing_canaries()的结果:
0000100000011100000000
11111111111111111111
答案 4 :(得分:0)
为什么不使用正则表达式?
print "Is INT\n" if ($test =~/-*\d+/);
print "Is FLOAT\n" if ($test =~/-*\d+\.\d+/);
#$test = "1234" = INT
#$test = "12.3" = FLOAT
重新编辑2019-12-24以在Perl(MHN)中正确运行
答案 5 :(得分:0)
我不确定您是否希望从变量中提取一个数字,或者是否要检查变量IS(可以是浮点数还是整数)。
但是,以上面的正则表达式示例为基础,它基本上是正确的,减去了一些调整。
#original code snippet
print "Is INT\n" if ($test =~/-*\d+/);
print "Is FLOAT\n" if ($test =~/-*\d+\.\d+/);
#$test = "1234" = INT
#$test = "12.3" = FLOAT
但是如果这是测试...
$test = "123.asd23aa"; # IS AN INT!!!!
尝试以下方法:
$test = "123.asd23aa";
print "Is INT\n" if ($test =~/-*\d+/); #NO ANCHORS, -* allows for multiple --
print "Is INT\n" if ($test =~/^-?\d+$/); # WITH ANCHORS, fixed -?
print "Is FLOAT\n" if ($test =~/^-?\d*\.\d+$/); #AS ABOVE, with \d* instead of \d+ (floats need not have a leading 0 . can start with .5 or -.5 etc)
这是一些简单的功能,您可以将它们放到可能具有的任何工具框中
sub isInt{
return ($_[0] =~/^-?\d+$/)?1:0;
}
sub isFloat{
return ($_[0] =~/^-?\d*\.\d+$/)?1:0;
}
sub isNum{
return (isInt($_[0]) || isFloat($_[0]) )?1:0;
}