in reply to How to determine whether a number has a decimal component?

Note, that period doesn't mean too much:

my $number = '1.00'; print "contains period\n" if $number =~ /\./; print "integer\n" if $number == int($number);

Replies are listed 'Best First'.
Re^2: How to determine whether a number has a decimal component?
by ikegami (Patriarch) on Jan 04, 2009 at 22:01 UTC

    Well you could use

    print "contains fractional component\n" if $number =~ /\.(?!0*$)/;

    But that'll fail for large numbers.

    sub r { $_[0] ? 'fractional' : 'integer' } for my $n ( '1.00', 2**50, ) { print( "$n:\n", "method 1: ", r( $n =~ /\./ ), "\n", "method 2: ", r( $n =~ /\.(?!0*$)/ ), "\n", "method 3: ", r( sprintf('%f',$n) =~ /\.(?!0*$)/ ), "\n", "method 4: ", r( int($_)!=$_ ), "\n", "\n", ); }
    1.00: method 1: fractional method 2: integer method 3: integer method 4: integer 1.12589990684262e+015: method 1: fractional method 2: fractional method 3: integer method 4: integer
      Shouldn't one use bignum either ways when going over 32 bit?

        Depends. It's a cost-benefit tradeoff. If the use of floats is appropriate, 53 bits of precision is probably way more than enough.

        By the way, Perl natively supports (without loss of precision) integer numbers (as in numbers without a fractional component) up to 2**53 (or higher depending on platform and build options), not 2**32-1.

Re^2: How to determine whether a number has a decimal component?
by ww (Archbishop) on Jan 04, 2009 at 23:29 UTC
    I think (but hope wiser heads will correct me if I err) that zwon's case, above rests on the use of non-interpolating quotes around \$number.

    Compare to this demo (which can be written much more compactly but was deliberately written in this tedious manner for utmost clarity):

    #!/usr/bin/perl -lw use strict; my $number0 = '1.00'; #zwon's version with NON-interpolating quotes my $number1 = 1.00; my $number2 = 1.393939393939393939393939393939393939393939393939393939 +3939393939; # exceeds length for FP precision my $number3 = 123456789.123e5; my $number4 = 123e-5; my $number5 = '123e-5' ; print "\$number0, $number0, contains a period" if $number0 =~ /\./; print "\$number0, $number0, is an Integer" if $number0 == int($number0 +); print "\$number1, $number1, contains a period" if $number1 =~ /\./; print "\$number1, $number1, is an Integer" if $number1 == int($number1 +); print "\$number2, $number2, contains a period" if $number2 =~ /\./; print "\$number2, $number2, is an Integer" if $number2 == int($number2 +); print "\$number3, $number3, contains a period" if $number3 =~ /\./; print "\$number3, $number3, is an Integer" if $number3 == int($number3 +); if ( $number4 =~ /\./ ) { # alt coding of the previous solely to + allow the else print "\$number4, $number4, contains a period"; } else { print "\tNo period in $number4"; } print "\$number4, $number4, is an Integer" if $number4 == int($number4 +); if ( $number5 =~ /\./ ) { print "\$number5, $number5, contains a period"; } else { print "\tNo period in $number5"; } print "\$number5, $number5, is an Integer" if $number5 == int($number5 +); print "\nNext, using ww's regex"; print "\n\$number0: $number0\n\$number1: $number1\n\$number2: $number2 +\n\$number3: $number3\n\$number4: $number4\n"; # CASE 0 $number0 =~ /\d+(\.)\d+/; if ($1) { print "\$number0 contains a decimal point"; } $number0 =~ s/(\d+)(\.)(\d+)/$1/; print "Integer value, if desired: $number0"; # CASE 1 $number1 =~ /\d+(\.)\d+/; if ($1) { print "\$number1 contains a decimal point"; } $number1 =~ s/(\d+)(\.)(\d+)/$1/; print "Integer value of \$number1, if desired: $number1"; # CASE 2 $number2 =~ /\d+(\.)\d+/; if ($1) { print "\$number2 contains a decimal point"; } $number2 =~ s/(\d+)(\.)(\d+)/$1/; print "Integer value of \$number2, if desired: $number2"; # CASE 3 $number3 =~ /\d+(\.)\d+/; if ($1) { print "\$number3 contains a decimal point"; } $number3 =~ s/(\d+)(\.)(\d+)/$1/; print "Integer value of \$number3, if desired: $number3"; # CASE 4 $number4 =~ /(\.)/; # Special case: Scientific notation if ($1) { print "\$number4 contains a decimal point"; } $number4 =~ s/(\d+)(\.)(\d+)/$1/; print "Integer value of \$number4, if desired: $number4"; # CASE 5 $number5 =~ /(\.)/; # Special case, as above if ($1) { print "\$number5 contains a decimal point"; } else { print "NO decimal point in \$number5, $number5"; } $number5 =~ s/(\d=)(\.)(\d+)/$1/; print "Integer value of \$number5, if desired: " . int($number5); # + using int(); otherwise prints the string literal

    Output:

    $number0, 1.00, contains a period $number0, 1.00, is an Integer # --> Note 1 $number1, 1, is an Integer $number2, 1.39393939393939, contains a period $number3, 12345678912300, is an Integer $number4, 0.00123, contains a period No period in 123e-5 Next, using ww's regex $number0: 1.00 $number1: 1 $number2: 1.39393939393939 $number3: 12345678912300 $number4: 0.00123 $number0 contains a decimal point Integer value, if desired: 1 $number1 contains a decimal point Integer value of $number1, if desired: 1 $number2 contains a decimal point Integer value of $number2, if desired: 1 $number3 contains a decimal point Integer value of $number3, if desired: 12345678912300 $number4 contains a decimal point Integer value of $number4, if desired: 0 NO decimal point in $number5, 123e-5 Integer value of $number5, if desired: 0
    --> Note 1: Arguable. Integer is defined "n : any of the natural numbers (positive or negative) or zero syn: whole number" and "whole number" is defined "(Math.), a number which is not a fraction or mixed number; an integer."

    Update: revised phrasing of the parenthetical comment about the tedious (kindergarten) code.

Re^2: How to determine whether a number has a decimal component?
by Xenofur (Monk) on Jan 04, 2009 at 16:12 UTC
    Thanks to you and also to kyle for demonstrating other reasons to avoid the first method.