проверить, является ли число int или float - PullRequest
6 голосов
/ 04 ноября 2010

В Perl я хочу проверить, содержит ли данная переменная число с плавающей запятой, а не. Чтобы проверить это я использую,

my $Var = 0.02 # Floating point number

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

   # floating point number
}

Но приведенный выше код не будет работать для 0.0,

Как мне этого добиться?

Ответы [ 4 ]

15 голосов
/ 04 ноября 2010

Это часто задаваемые вопросы.См. Как определить, является ли скаляр числом / целым / целым / с плавающей точкой?

Вы также можете использовать 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 от 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

Мне кажется, что проверка должна была бы просто посмотреть, если NOKфлаг установлен.Мне требуются годы, чтобы написать даже самый простой XS, поэтому я не буду предоставлять реализацию.

7 голосов
/ 14 марта 2013
($Var - int($Var))?'float':'int'
1 голос
/ 06 августа 2014

Вы можете использовать autobox :: универсальный модуль, который является частью 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
0 голосов
/ 16 апреля 2019

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 

Результаты 'did_this_variable_look_like_a_perl_float ():

0000000000000000000000
11111111111111111111

Результаты is_convertable_to_float__casting_and_killing_canaries ():

0000100000011100000000
11111111111111111111
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...