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

Hi Monks, All i simply want to do is check for the presence of two numbers in an array, then save these and everything in between to a new array.

The problem is that simply testing for the presence of the first number returns negative, even though printing out the number and the array suggest they should definately match. Can anyone please help?

my $first_num = $highest[0]; # print $first_nums gives 0.743499999999 +99 for (my $i=0; $i < @array; $i++) { if ($first_num) { if ($array[$i] == $first_num) { print "FOUND! \n"; } } }

Replies are listed 'Best First'.
Re: Extracting numbers from arrays
by BrowserUk (Patriarch) on Jun 30, 2003 at 14:17 UTC

    Abigail's solution is probably the best answer to your overall problem although it may not be the complete answer.

    I think the main reason you were not finding the second number equal to the first even though it appeared to be there when you printed it out, is due to floating point round-off.

    Basically, when you output floating point numbers using print, they may appear to have the same value, but this is due to them being rounded to a certain number of signifucant digits by default. The may look the same, but test them for equality using ==, and you will get false because they aren't actually identical at the binary level.

    See the thread at Bug? 1+1 != 2 for some detailed explainations of the problem and how to work around it.


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


Re: Extracting numbers from arrays
by dragonchild (Archbishop) on Jun 30, 2003 at 13:09 UTC
    Add "use strict;" to the top of your script. Next, your snippet seems ill-suited to the task you describe. I would look at doing something like:
    use strict; my ($first, $last) = @ARGV; # Pass the values in my @nums = 1 .. 100; my $inside = 0; my @inside_nums; foreach my $num (@nums) { if ($num == $first) { $inside = 1; } if ($inside) { push @inside, $num; } if ($num == $last) { $inside = 0; } } print "@inside\n"; #### for-loop could also be written as: my $inside; foreach my $num (@nums) { $inside = 1 if $num == $first; push @inside_nums, $num if $inside; $inside = 0 if $num == $last; }
    Have fun with the rest of your homework.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: Extracting numbers from arrays
by davorg (Chancellor) on Jun 30, 2003 at 13:10 UTC

    Maybe a use for grep. Set $first and $last to the two numbers you're looking for.

    my $flag; my @new = grep { $flag = 1 if $_ == $first; $flag = 0 if $_ == $last; $flag } @old;

    Of course, this breaks if you have multiple occurances of your target numbers.

    Update: Abigail-II is right of course. The flip-flop operator (..) does exactly what I wanted. Shame it dropped out of my head temporarily as I was writing this reply :(

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      Why not use an operator that does exactly that?
      my @new = grep {$_ == $first .. $_ == $last} @old

      Abigail

Re: Extracting numbers from arrays
by Skeeve (Parson) on Jul 01, 2003 at 06:49 UTC
    Just to add another idea of how to do it...
    @a=qw(1 2 3 4 5 6 7 8 9 2 3 1 4 5 6 7 8 9 1 4); $first=3; $last=1; @l{@a}=0..$#a; @f{reverse @a}=reverse 0..$#a; print join ' ',@a[$f{$first}..$l{$last}],"\n";
    This solves the problem by storing the first and last index of each number in %f and %l. Then you can get the whole slice between both numbers.

    Maybe you want to use

    @a[$f{$first}..$l{$last}>=$f{$first}?$l{$last}:$#a]
    to get the complet rest of the array if the last number isn't behind the first.