Perl 检查数字是int还是float
在perl中,我想检查给定变量是否包含not的浮点数。要检查我使用的这个Perl 检查数字是int还是float,perl,types,Perl,Types,在perl中,我想检查给定变量是否包含not的浮点数。要检查我使用的这个 my $Var = 0.02 # Floating point number if (int($Var) != $Var) { # floating point number } 但是上面的代码不适用于0.0 我如何才能做到这一点?这是一个常见问题解答。看 您也可以使用 有趣的是 #!/usr/bin/perl use strict; use warnings; use Scalar::Util::Numer
my $Var = 0.02 # Floating point number
if (int($Var) != $Var) {
# floating point number
}
但是上面的代码不适用于0.0
我如何才能做到这一点?这是一个常见问题解答。看
您也可以使用
有趣的是
#!/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
和0.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;
输出:
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
INTEGER
FLOAT
SV=0x182c0fc处的NV(0x18683cc)
REFCNT=1
标志=(PADMY、NOK、pNOK)
NV=0
在0x182c19c处,SV=IV(0x182c198)
REFCNT=1
FLAGS=(PADMY、IOK、pIOK)
IV=0
SV=0x182c19c时的PVNV(0x397ac)
REFCNT=1
标志=(PADMY、NOK、pNOK)
IV=0
NV=0
PV=0
在我看来,检查只需查看是否设置了
NOK
标志。即使是最简单的XS,我也要花很长时间来编写,因此我不会提供实现。您可以使用autobox::universal module,它是其中的一部分
($Var - int($Var))?'float':'int'
输出:
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
INTEGER
FLOAT
如果变量字符串是浮点,Perl5返回true或false:
您必须通过巧妙地使用正则表达式和处理边缘情况来实现自己的功能,或者遵从第三方库并捕获和抑制它们抛出的异常
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
这个变量看起来像perl浮点()吗:
0000000000000000000000
11111111111111111111
0000100000011100000000
11111111111111111111
可转换为浮动铸造和杀死金丝雀()的结果:
0000000000000000000000
11111111111111111111
0000100000011100000000
11111111111111111111
为什么不使用正则表达式呢
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)我不确定您是否希望从变量中提取一个数字,或者是否希望检查该变量是(可以是)浮点还是int 然而,在上面的正则表达式示例的基础上,它基本上是正确的,只需做一些调整
#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;
}
您必须查看是否有不同于NV的IV。使用基于glibc的系统,您可以区分:
$x eq-$x?“IV':“NV”
你的问题的正确答案完全取决于你想知道的原因。对于浮点数,您打算做什么不同的处理?警告:这将把字符串称为“int”。它验证数字,但不能保证$Var
实际上是数字。[审阅者注意]:我已经格式化了代码,并添加了=
比较运算符,而不是单个=
。我不是perl专家,但如果我做错了什么,请在评论中标记我。干杯。“==”在Perl中不适用。“=~”用于正则表达式,因此您的编辑无效。下面是一个示例:1)使用编辑:$perl-e'$test=“123.45”;如果($test==~/-*\d+\.\d+/);,则打印“是浮点\n”[无输出!!!]2)使用正确的Perl语法:$Perl-e'$test=“123.45”;如果($test=~/-*\d+\.\d+/);,则打印“是浮点\n”是浮点型,请在进行编辑之前记住正在使用的编程语言;-)你是完全正确的,为匆忙的编辑感到抱歉。也谢谢你的例子没问题,妮卡!至少可以说Perl是一个奇怪的野兽!