Mailing List

Nested
comparison of negative numbers
User: lorik
Date: 5/19/2010 4:22 pm
Views: 193
Rating: 0

Hello, This routine works fine with postive numbers, but not with negative numbers. Why is this, and is there a work-around? Thank you.

 

%storeSlnValue =('largest'=> -1,
          'second largest'   => -2,
          'third largest'   => -3,
          'fourth largest'  => -4,
);


while ( ( $key, $value ) = each %storeSlnValue ) {
            print "This is the value: $value\n";
            $maxSlnValue = $value if $maxSlnValue < $value;
            print "This is the maxSlnValue: $maxSlnvalue\n";
}

Re: comparison of negative numbers
User: hoelzro
Date: 5/19/2010 4:40 pm
Views: 0
Rating: 0
Greetings, lorik.

First of all, trying using strict and warnings.  They'll help you find
a lot of problems really quickly.

Problem 1: You misspelled $maxSlnValue in the last print statement; which could just be from posting this to the list.
Problem 2: When your code runs, $maxSlnValue starts with a value of undef, which (iirc) serves as a value of 0 in a numeric comparison.  Since 0 is still larger than all negative numbers,
 $maxSlnValue < $value is never true, thus $maxSlnValue never gets updated.

-Rob

On Wed, 19 May 2010 16:22:29 -0500
wrote:

> lorik wrote:
>
> Hello, This routine works fine with postive numbers, but not with
> negative numbers. Why is this, and is there a work-around? Thank you.
>
>  
>
> %storeSlnValue =('largest'=> -1,
>           'second largest'   => -2,
>           'third largest'   => -3,
>           'fourth largest'  => -4,
> );
>
>
> while ( ( $key, $value ) = each %storeSlnValue ) {
>             print "This is the value: $value\n";
>             $maxSlnValue = $value if $maxSlnValue < $value;
>             print "This is the maxSlnValue: $maxSlnvalue\n";
> }
>
> View Online
Re: comparison of negative numbers
User: mcholste
Date: 5/19/2010 4:50 pm
Views: 0
Rating: 0
$maxSlnValue should be initialized properly above your "each" loop,
for starters.  Are you using strict or is this pseudo-code?  When you
init to 0, you'll see why it doesn't work--0 is always greater than
any of the values in the hash, so $maxSlnValue is never smaller than
$value, and therefore it never gets changed.  Perl will evaluate undef
to zero in numeric comparisons (though it should throw a warning).
For this to work with negative numbers, init $maxSlnValue to a very
large negative number, such as 2**32 * -1;

However, perhaps a better way is to use the sort built-in like this:

my $largest = (sort { $b > $a } values %storeSinValue)[0];

--Martin

On Wed, May 19, 2010 at 4:22 PM,   wrote:
> lorik wrote:
>
> Hello, This routine works fine with postive numbers, but not with negative
> numbers. Why is this, and is there a work-around? Thank you.
>
>
>
> %storeSlnValue =('largest'=> -1,
>           'second largest'   => -2,
>           'third largest'   => -3,
>           'fourth largest'  => -4,
> );
>
>
> while ( ( $key, $value ) = each %storeSlnValue ) {
>             print "This is the value: $value\n";
>             $maxSlnValue = $value if $maxSlnValue < $value;
>             print "This is the maxSlnValue: $maxSlnvalue\n";
> }
>
> View Online
>
>
> Madison Area Perl Mongers - MadMongers
> http://www.madmongers.org
>
>
Re: comparison of negative numbers
User: afbach
Date: 5/19/2010 6:07 pm
Views: 0
Rating: 0
>
> On Wed, May 19, 2010 at 4:22 PM,   wrote:

>> %storeSlnValue =('largest'=> -1,
>>           'second largest'   => -2,
>>           'third largest'   => -3,
>>           'fourth largest'  => -4,
>> );
>>
>>
>> while ( ( $key, $value ) = each %storeSlnValue ) {
>>             print "This is the value: $value\n";
>>             $maxSlnValue = $value if $maxSlnValue < $value;
>>             print "This is the maxSlnValue: $maxSlnvalue\n";
>> }

You can use the fact that $maxSlnValue is undef as a marker (assuming
you won't have any undef values in the hash):
my $maxSlnValue;
while ( my ( $key, $value ) = each %storeSlnValue ) {
            print "This is the value: $value ($key)\n";
            $maxSlnValue = $value
               if not defined $maxSlnValue or $maxSlnValue < $value;
            print "This is the maxSlnValue: $maxSlnValue\n";
}

This is the value: -2 (second largest)
This is the maxSlnValue: -2
This is the value: -3 (third largest)
This is the maxSlnValue: -2
This is the value: -4 (fourth largest)
This is the maxSlnValue: -2
This is the value: -1 (largest)
This is the maxSlnValue: -1


Just a style note - while is a particular choice for iterating through
a hash, for/foreach (these two are the same, despite many folk's
belief otherwise [1]) w/ 'keys' is the usual route.
foreach my $key ( keys %storeSinValue ) {
  my $value = $storeSinValue{$key};
...

But while/each  is good If you are going to work w/ every key and value.

a


[1]
perldoc perlsyn
      The "foreach" keyword is actually a synonym for the "for"
keyword, so you can use "foreach" for readability or
      "for" for brevity.  (Or because the Bourne shell is more
familiar to you than csh, so writing "for" comes more
      naturally.)  If VAR is omitted, $_ is set to each value.


--



Andy Bach,
afbach@gmail.com
608 658-1890 cell
608 261-5738 wk
PreviousNext
Madison Area Perl Mongers