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

Hi fellow Monks,
I am new to programming and I have a rather newbie question:
I have a for loop that will calculate some stuff and return a number as a result. This number I have to check each time (until the loop finishes) if it has the highest value (max value). My question is, before I start the loop, how will I declare the variable for the max number? For strings, I know it is $string=''; I can't use $max_numb=0; because I might get negative numbers as well.
The for loop will be something like that:
$max_numb= ???????? --->what should I use here? for($i=0; $i<=100; $i++) { $number_to_compare=..........; if($number_to_compare>$max_numb) { $max_numb=$number_to_compare; } } print $max_numb;

Replies are listed 'Best First'.
Re: undef number?
by toolic (Bishop) on Apr 18, 2010 at 01:25 UTC
    I can think of 2 approaches:

    1. Seed your $max_numb with your 1st $number_to_compare, then loop through one less:

    $number_to_compare=..........; $max_numb=$number_to_compare; for($i=1; $i<=100; $i++)

    2. push all your $number_to_compare into an array (you only have 101), then use List::Util::max:

    use List::Util qw(max); my @nums; for my $i (0 .. 100) { my $number_to_compare = ..........; push @nums, $number_to_compare; } my $max_numb = max(@nums);
Re: undef number?
by BrowserUk (Patriarch) on Apr 18, 2010 at 01:23 UTC

    I usually use -1e308, through strictly the smallest number that Perl can store is: -1.797693134862314e308.

Re: undef number?
by ikegami (Patriarch) on Apr 18, 2010 at 01:57 UTC
    Any value in your list would do, such as the first value $number_to_compare will take.
    my $max = $numbers[0]; for (@numbers) { $max = $_ if $_ > $max; }

    Update: Added example.

      That's right. The OP is not really looking for the biggest number that perl can express, but the biggest number of his own collection.

      Peter (Guo) Pei

Re: undef number?
by Xilman (Hermit) on Apr 18, 2010 at 08:31 UTC

    Why not just initialize $max_numb to the first value of $number_to_compare and then run the loop from $i=1 instead?

    Paul

Re: undef number?
by bart (Canon) on Apr 18, 2010 at 19:30 UTC
    This is a trick I learned from tye. You can calculate a number that is so absurdly high, that it must be stored internally as inf (infinite).
    use constant INF => 9**9E9; print INF;
    Output:

    1.#INF

    Oddly enough, comparisons still work, in every Perl version I've tested so far:

    use constant INF => 9**9E9; local($\, $,) = ("\n", "\t"); for my $e (305 .. 310) { my $n = 10**$e; print $e, $n, INF > $n || 0, -$n, -(INF) < - $n || 0; }
    Result:
    305 1e+305 1 -1e+305 1 306 1e+306 1 -1e+306 1 307 1e+307 1 -1e+307 1 308 1e+308 1 -1e+308 1 309 1.#INF 0 -1.#INF 0 310 1.#INF 0 -1.#INF 0
    (On another perl I see "inf" instead of "1.#INF", but other results are identical.)

    As you can see, even the unary minus sign (negate) still works as it ought to.

    Unfortunately(?) INF is still not bigger than INF, but... I guess that won't matter any more, will it?

Re: undef number?
by jwkrahn (Abbot) on Apr 18, 2010 at 01:36 UTC
    This number I have to check each time (until the loop finishes) if it has the highest value (max value).

    Don't you have a maximum value in mind?    If you want it to hold the maximum value that Perl defines for a number then how do you expect $number_to_compare to ever be greater than it?

Re: undef number?
by Anonymous Monk on Apr 18, 2010 at 17:56 UTC
    There is another approach:
    use List::Util qw(max); my $max_numb = max(map { generate_number($_) } 0..99); sub generate_number { my $index = shift; #... }
Re: undef number?
by Marshall (Canon) on Apr 19, 2010 at 10:59 UTC
    I would suggest a different method... In Perl if you have some @x and you want to find the maximum value, the easy way is to just sort @x and take the last element with a slice...like below. The -1 index means "last one". Note that this will work for max,min even if there is only one thing in @x. Now granted sort is slower than some one pass "is this the biggest algorithm" but it is very simple to use and is faster than you might think. Use the power of the language and optimize later if you need to.
    #!/usr/bin/perl -w use strict; my @x =(56, 78, 3, -1, 15); my ($max, $min) = (sort {$a <=> $b} @x)[-1,0]; print "max = $max, min =$min\n"; #prints: max = 78, min =-1
    updated: numeric sort
    the default is alphabetic comparison and that would give -1 15 3 56 7 78 which of course isn't right! So specifying $a <=> $b specifies the "spaceship" operator, a numeric comparison rather than the default of $a cmp $b which is an alpha comparison.

    update again: see ikegami's post.

      the easy way is to just sort @x and take the last element with a slice...

      There's no way I would call

      (sort {$a <=> $b} @x)[-1,0]
      easier than
      max(@x)

      They're both core, max being located in List::Util.

        Didn't realize this was core, but indeed it is! And also List::Util::XS so one can see if List::Util was installed as C compiled version. Sometimes it is easy to forget that the Camel book only has a subset of Core modules listed as there are a lot of them now.

        thanks.