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

Hi all, Is it possible to match a number with in +/- a few decimal places. For example my input value is 5.56, i search a list of true values (pattern match) if the values match then fine. However, if it doesnt match i want to match any numbers stored than are with +/- 0.1 of the input value. Is this possible?
$input = 5.56 open (FH, "<listofvalues"); while (<FH>) { ^/(S+\.S+).*/ if $1 == $in {print value in list} else increment $in by +/- 0.1 and search again if match print value in list otherwise print not in list
thanks

Replies are listed 'Best First'.
Re: matching a number
by tlm (Prior) on May 31, 2005 at 16:12 UTC

    Why not just simple arithmetic for this?

    while ( <FH> ) { chomp; if ( abs( $input - $_ ) <= 0.1 ) { print "Value in list\n"; last; } }

    Update: The original version of the above was overly complicated. I simplified it significantly, though the basic idea is the same.

    the lowliest monk

Re: matching a number
by BigRare (Pilgrim) on May 31, 2005 at 16:18 UTC
    It looks like what you want is to search for a range.

    Example:
    if (($input - 0.1) <= $1 && $1 <= ($input + 0.1)) { <insert code here>; }
Re: matching a number
by trammell (Priest) on May 31, 2005 at 16:35 UTC
Re: matching a number
by chas (Priest) on May 31, 2005 at 16:38 UTC
    If you actually need to extract the number with a regex you can use something like:
    while(<F>){ /(\d+\.\d+)/; if (abs($1 - 5.56)<=.1) {print $1,"\n"} }

    (If there is more than one number on a line, you'll have to do something a little different, but it looks like that's not the case from your original code.)
    chas
    (Update: I'm now a little unhappy about this because I noticed that abs(5.56-5.66)<=.1 returns false. I wonder if Test::Number::Delta as suggested by trammell is more reliable in this respect. From the docs it looks like it may not be, but I haven't tried it...)
      Minor tweak to make sure the $1 is used IFF the regex succeeds:
      while(<F>){ next unless /(\d+\.\d+)/ && abs($1 - 5.56)<=.1; print $1,"\n"; }