检查数字是否为int或float

时间:2010-11-04 05:06:04

标签: perl types

在perl中,我想检查给定变量是否保持浮点数不是。要检查我正在使用,

my $Var = 0.02 # Floating point number

if (int($Var) != $Var) {

   # floating point number
}

但上述代码不适用于0.0,

我怎样才能做到这一点?

6 个答案:

答案 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)

如果变量字符串是浮点型,则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 

“ 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;
}