derpp has asked for the wisdom of the Perl Monks concerning the following question:

Hey guys.

I'm writing a very simplified program that finds all the factors of any number you input.

Here's how it goes:
print "Enter a number you want to factor: \n"; $number = <STDIN>; for ($count = 2; $count <=sprintf($number/2); $count++) { $result = $number / $count; { push (@factor, $result); } } print "The factors of $number are: \n"; foreach (@factor) { print "$_\n"; }
The problem is, it prints decimals as well as factors. Please help?

Replies are listed 'Best First'.
Re: how to make perl only print whole numbers
by moritz (Cardinal) on Aug 03, 2010 at 22:05 UTC
    You can divide every number by 2 (or by any number other than zero), you just won't always get an integer result.

    That's why your code prints also fractional numbers - it never checks for integer divisibility.

    One good way to do that is to use the % infix operator (modulus operation), which gives you the reminder of a division. So for example 7 % 3 is 1, because if you divide 7 by 3, the remainder is one. If the remainder is zero, the second number evenly divides the first.

    Perl 6 - links to (nearly) everything that is Perl 6.
      thanks :) that really helped.

      Update: nevermind, sigh.

      Just to be boldly pedantic...

      You can divide every number by 2 (or by any number other than zero or one), you just won't always get an integer result.

        Every number includes 1.5, and 1.5 / 1 does not give an integer result.

        The OP code even allows you to enter such numbers, since the input has no validation at all.

Re: how to make perl only print whole numbers
by aquarium (Curate) on Aug 04, 2010 at 00:26 UTC
    the loop conditional should be pre-computed, instead of performing same calculation and sprintf on every iteration.
    also..wondering why you have the braces around the push, as there's no control statement..those braces do nothing?
    the hardest line to type correctly is: stty erase ^H
      Moreover, if you are iterating until (number/2) in order to find number's *prime* factors, then you're on a wrong way, since the right condition would be to iterate until sqrt(number).
Re: how to make perl only print whole numbers
by toolic (Bishop) on Aug 04, 2010 at 01:35 UTC
    Unrelated to your problem... don't use sprintf that way. The first argument should be a FORMAT.
Re: how to make perl only print whole numbers
by Anonymous Monk on Aug 04, 2010 at 03:17 UTC
    It might also interest you to examine Math::Big::Factors.

    Here's one way to use it, that produces pretty output. You can pipe or pass as an argument a number to factor.

    use strict; use warnings; use feature qw(say); use Math::Big::Factors qw(factors_wheel); use List::AllUtils qw(max); for my $number (@ARGV ? @ARGV : <STDIN>) { chomp $number; # in case it came from stdin my %factors; $factors{$_}++ for factors_wheel($number, 1); my (@sup, @fac); for my $factor (sort { length($a) <=> length($b) or $a <=> $b +} keys %factors) { my $exp = $factors{$factor}; my $fmt = "%${\(length$factor)}s%${\(length$exp)}s"; push @sup, sprintf($fmt, '', $exp); push @fac, sprintf($fmt, $factor, ''); } my $pfx = "\t"; say join("\n", "$number:", $pfx . join(' ', @sup), $pfx . join(' * ', @fac), ''); }
Re: how to make perl only print whole numbers
by suhailck (Friar) on Aug 04, 2010 at 03:39 UTC
    A regex solution,

    perl -le '("1" x shift)=~/^(11+)\1+$(?{print length $1})(*FAIL)/' 30 15 10 6 5 3 2


    ~suhail
Re: how to make perl only print whole numbers
by aguilarsoto (Novice) on Aug 03, 2010 at 22:03 UTC
Re: how to make perl only print whole numbers
by biohisham (Priest) on Aug 04, 2010 at 07:22 UTC
    for ($count = 2; $count <=sprintf($number/2); $count++) { $result = $number / $count; { <-------------------------------- Extra Block.. push (@factor, $result); } <-------------------------------- Extra Block.. }
    There's no need for the extra block embracing push(@factor, $result)...

    While you can use sprintf, printf or even int to chop away the decimal part the array @factor can end up having repeated elements and that doesn't sound efficient..exercise on some workaround and we'll be here if you needed assistance . :)

    Make it a habit to always declare your variables and turn strictures on at the top of your program that can save you from many horrendous evil bugs that can become hard to track otherwise...

    use strict; use warnings; print "Enter a number you want to factor: \n"; my $number = <STDIN>; my @factor; for (my $count = 2; $count <=sprintf($number/2); $count++) { my $result = int($number / $count); #other approaches were shown.. push (@factor, $result); } print "The factors of $number are: \n"; foreach (@factor) { print "$_\n"; }


    Excellence is an Endeavor of Persistence. A Year-Old Monk :D .