in reply to Range check with unordered limits

$inRange = (($a <=> $x) * ($b <=> $x)) < 1;

This appears to give the same result:

$inRange = (($a - $x) * ($b - $x)) < 1;

Replies are listed 'Best First'.
Re^2: Range check with unordered limits
by hv (Prior) on Jul 10, 2022 at 23:14 UTC

    That would work in most cases. The original code would also work for floating point values, whereas this version would need to change to ... <= 0 to handle that correctly. Under `use integer` it could also give the wrong answer due to overflow. In the general case it would be no faster than the original code, and can be slower.

      > whereas this version would need to change to ... <= 0

      IMHO for a multiplying approach that's the best check, even for the <=> version.

      Simply changing to ... < 0 would check for the open interval excluding the endpoints. And ... == 0 for endpoints only.

      But half-open intervals like [$a,$b[ can't be covered with this approach.

      So I'd rather stick with

      • $a <= $x and $x < $b
      or the newer chained version
      • $a <= $x < $b
      and make sure the endpoints are previously swapped if necessary
      • ($a,$b) = ($b,$a) if $b < $a;
      update

      and swapping can be made non-destructive by localizing it to a scope.

      C:\tmp\e>perl ($a,$b) = (7,3); my $x=5; my $inside = do { local ($a,$b) = ($b,$a) if $b < $a; $a <= $x < $b ; }; print "$x in [$a, $b]? $inside"; __END__ 5 in [7, 3]? 1 C:\tmp\e>

      (replace local with my for private vars)

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery