Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Spaceship Zero

by Orchew (Acolyte)
on Nov 09, 2008 at 05:40 UTC ( [id://722455]=obfuscated: print w/replies, xml ) Need Help??

AFAIK there's no perl built-in function to return the sign of a number, something like sgn($x). In some languages I've used $x/abs($x), and but that won't handle zeros.

I call my solution Spaceship Zero:

$x<=>0 ;# sgn($x)
I'm fairly confident that, in perl, that is the shortest possible way to calculate sgn($x).

Replies are listed 'Best First'.
Re: Spaceship Zero
by Anonymous Monk on Nov 09, 2008 at 12:27 UTC
    that also won't handle zeros, nor will it return a sign exactly :)

      "that also won't handle zeros, nor will it return a sign exactly :)"

      Care to explain what you mean that it won't handle zeros? It looks to me like you have never used a sign, sgn or signum function before. It returns 1 for a positive, 0 for zero and -1 for a negative. This behaves exactly like other sign functions do.

        Care to explain what you mean that it won't handle zeros?

        I think he's referring to the discrepancy between the documented behaviour (returning the sign of the number) and the actual behaviour (returning 0) for both positive and negative zeros.

        $ perl -le'$x=+0.0; print $x; print $x<=>0' 0 0 $ perl -le'$x=-0.0; print $x; print $x<=>0' -0 0

        It does produce the documented results for +inf and -inf, and a sane result for NaN.

        $ perl -wle'$x=0+Infinity; print $x; print $x<=>0' inf 1 $ perl -wle'$x=0-Infinity; print $x; print $x<=>0' -inf -1 $ perl -wle'$x=0+NaN; print $x; print $x<=>0' nan Use of uninitialized value in print at -e line 1.
        I think there may be some justifiable confusion between something like the "sgn()" function in BASIC, which does work just like the spaceship operator (returning -1 or 0 or 1), and something else that is more like the "copysign" function in C. There's probably a natural tendency to want to do something like this:
        $delta_to_add = $magnitude * $direction; $value += $delta_to_add;
        where direction is "1" for "up" and "-1" for "down"; but imagine a case where $magnitude is not zero, and $direction could be derived from or based on any value whatsoever, such that anything non-negative should count as "positive". You want to "copy" the sign bit from $direction onto $magnitude, but Perl doesn't really have a "copysign" function, and your "standard sgn()" function (like the spaceship operator) would do the wrong thing by returning zero when basis for $direction is zero, thereby setting $delta_to_add to zero as well.

        I used to think there was a function that would return -1 for values less than 0, and 1 otherwise, so that you could simply use the multiplication operator to copy the sign of one variable onto another. I also dimly recall at least one discussion about this at the Monastery, but now I can't seem to locate either such a function or the previous debate. Oh well...

        (updated slightly in hopes of making the 2nd paragraph clearer)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: obfuscated [id://722455]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (3)
As of 2024-04-24 19:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found