Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: perl typecasting

by adamk (Chaplain)
on Feb 04, 2008 at 23:47 UTC ( [id://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

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
Domain Nodelet?
Node Status?
node history
Node Type: note [id://666150]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (4)
As of 2024-04-25 07:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found