http://www.perlmonks.org?node_id=144360

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

i ran into the problem where my program would sometimes be forced to take negative square roots. I tried to catch an error somewhere in the function, but couldn't do so. I've tried the following:
eval { $number = sqrt(-1) }; if ($@) { print "negative sqrt"; }
and
$number = sqrt(-1) or die "error";
and
$number = sqrt(-1) or print "error";
all with no luck. Math::Complex manages to take negative squareroots, but i didn't wanna bother doing that. The only good solution i can come up with right now is checking for a negative number before performing the function. Any ideas on alternatives?

Replies are listed 'Best First'.
Re: negative sqrt()
by Fletch (Bishop) on Feb 09, 2002 at 16:04 UTC

    The eval works fine, so long as you're not passing a constant -1 as an argument (which the compiler will catch and gripe about). Compare:

    $ perl -le 'BEGIN { print "in begin" } eval { $i = <> ; $r = sqrt( -1 +) }; print ($@ ? "error: $@" : $r)' + in begin Can't take sqrt of -1 at -e line 1.

    with

    echo -1 | perl -le 'BEGIN { print "in begin" } eval { $i = <> ; $r = s +qrt( $i ) }; print ($@ ? "error: $@" : $r)' + in begin error: Can't take sqrt of -1 at -e line 1, <> line 1.
(jeffa) Re: negative sqrt()
by jeffa (Bishop) on Feb 09, 2002 at 15:48 UTC
    $ perldoc -f sqrt
    
      sqrt EXPR
      sqrt    Return the square root of EXPR.  If EXPR is
              omitted, returns square root of "$_".  Only works
              on non-negative operands, unless you've loaded the
              standard Math::Complex module.
    
              use Math::Complex;
              print sqrt(-2);    # prints 1.4142135623731i
    

    UPDATE:
    But i didn't really answer the question, "why can't you 'catch' this exception" ... is it possible? Why yes it is! Fletch++!

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)