Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: perl typecasting

by adamk (Chaplain)
on Feb 04, 2008 at 23:47 UTC ( #666150=note: print w/ replies, xml ) Need Help??


in reply to perl typecasting

If by "integer" you mean "positive integer" then the simplest way might be the _POSINT(...) function in Params::Util.

If you mean in a stricter sense (allowing zero and/or negatives) then take a look at the bulkier-but-far-more-complete Regexp::Common module.

It almost certainly has more format testers than you can possibly use.

http://search.cpan.org/~abigail/Regexp-Common-2.120/lib/Regexp/Common.pm


Comment on Re: perl typecasting
Replies are listed 'Best First'.
Re^2: perl typecasting
by perl_junkie (Acolyte) on Feb 05, 2008 at 00:21 UTC
    These are the 2 validation subroutines I have used for integer and decimal data type checks. I am preparing to load the data into DB2 database after this process, so the data types are defined accordingly. I am not too good with regular expressions, so have tried to code to the best of my knowledge using other functions.

    ############# SUB-ROUTINE TO CHECK FOR INTEGER TYPE ############## #check for small int, big int and int data types and return a 0 if cor +rect # else return a 1 sub int_chk { my $input = shift; $input = $input+0; if ($data_type eq 'SMALLINT') { if ($input > -32768 && $input < 32768) { return $positive; } else { return $negative; } } elsif ($data_type eq 'INTEGER') { if ($input > -2147483648 && $input < 2147483647) { return $positive; } else { return $negative; } } elsif ($data_type eq 'BIGINT') { if ($input > -9223372036854770000 && $input < 9223372036854770000) { return $positive; } else { return $negative; } } else { return $negative; } } ############ SUB-ROUTINE TO CHECK FOR DECIMAL TYPE ############## sub decimal_chk { #Here, I get a decimal input and separate it into 2 separate integers # say 123.45 split into 123 and 45 # I need to check if -999 < 123 < 999 and -99 < 45 < 99 . my $data=shift; my $index=index($data,".")+1; $main=substr($data,0,$index-1); #print "Integer part is $main\n"; if ($index > 0) { $prec=substr($data,$index,length($data)-($index)); } else { $prec=''; } $u_len=length($main); $l_len=length($prec); $upper=9; $lower=9; for ($u_count = 1; $u_count < $u_len; $u_count++) { $upper=$upper."9"; } for ($l_count = 1; $l_count < $l_len; $l_count++) { $lower=$lower."9"; } # 123.45 will be declared as decimal(5,2), 2 being the decimal length if ($main > (-1*$upper) && $main < $upper) { if ($prec > (-1*$lower) && $prec < $lower) { if (($u_len <= ($data_precision-$data_dec_len)) && ($l_len <= +$data_dec_len)) # Final length check with specified lengths { return $positive; } else { return $negative; } } else { return $negative; } } else { return $negative; } }

      I carefully read your code and made a few tweaks to it. You are making a good start. Read and reread the docs, ask questions and keep working at it. I strongly recommend that you take the time to understand regexes. They are a very, very, useful and powerful tool.

      I noticed some problems with your code as I read it.

      • You have inconsistent use of inclusive vs exclusive comparisons.
      • Your algorithm for floating point validation would allow numbers like '12. 3' (that's a space between the . and the 3) to pass.
      • There are a number of variables that seem to come from nowhere. Are they globals?
      • You are using C style for loops.

      For loops in perl are usually done as follows:

      # You had for ($l_count = 1; $l_count < $l_len; $l_count++) { $lower=$lower."9"; } # Try this instead: for my $l_count ( 1..$l_len ) { $lower=$lower."9"; } # To build up a string like this you should be using the 'x' operator my $lower = '9' x $l_len;

      Here's your code with my tweaks applied. What follows is untested, but should work.

      use constant MATCH => 1; # Return value for good match use constant FAIL => 0; # Retrun value for failed match use constant MIN => 0; # Index of minimum value for integer checks use constant MAX => 1; # Index of maximum value for integer checks ############# SUB-ROUTINE TO CHECK FOR INTEGER TYPE ############## #check for small int, big int and int data types and return a 0 if cor +rect # else return a 1 sub int_chk { my $input = shift; my $data_type = shift; # Where was this coming from in your code? $input = $input+0; # Test for integerness if ( $input != int( $input ) ) { return FAIL; } # Use a hash lookup to simplify your code. my %check = ( # type MIN + MAX SMALLINT => [ -32768, 32767 ], INTEGER => [ -2147483648, 2147483647 ], BIGINT => [ -9223372036854770000, 9223372036854770000 ], ); # Test for range if ( exists $check{$data_type} ) { my $match = ( $input >= $check{$data_type}[MIN] # I used inclusive range +s here and $input <= $check{$data_type}[MAX] ) ? MATCH : FAIL; return $match; } else { return FAIL; } die "Unreachable code executed"; } sub decimal_chk { my $input = shift; my $whole_places = shift || 3; # Set a default value my $decimal_places = shift || 2; # for each of these args return $input =~ / ^ # Start of input -? # Optional minus sign \d{0,$whole_places} # 1-? whole number digits ( \. # Manadatory decimal point \d{0,$decimal_places} # 1-? decimal places )? # decimal section is optional $ # End of input /x ? MATCH : FAIL ; # x modifier allows comments and whitespac +e }


      TGI says moo

        TGI, I really appreciate you taking time off to review my code. Thanks..!!!

        I am working on my regex skills now. I should get better at it in the coming weeks.

        The variables I have not defined are globals.. sorry I should have mentioned that... Your code looks much cleaner and easier to debug than mine...!!!! Thanks a lot...!!!!!

        I have got a lot of people telling me about using the modules. Can anyone give me info on how I can check this. Everytime I use this, I get this error message.

        "Can't locate Regexp/Common.pm in @INC (@INC contains: /etrade/pkgs/perl/5.8.0_crm/lib/perl5 /etrade/pkgs/perl/5.8.0_crm/lib/perl5/site_perl /etrade/pkgs/perl/5.8.0_crm/lib/site_perl /usr/perl5/5.00503/sun4-solaris /usr/perl5/5.00503 /usr/perl5/site_perl/5.005/sun4-solaris /usr/perl5/site_perl/5.005 .) at dm.pl line 3."

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://666150]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (15)
As of 2015-07-07 18:44 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (93 votes), past polls