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

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

This is how I thought I can negate a number:
$p = 7; $n = -$p; # or 0 - $p print $n; # -7 printf "%x", $n; # FFFFFFF9
But in the document i'm reading, it says to negate the number, and the example says the result of negating 0x0007 is FFF8. I looked on the web, and found someone gave an example of negating a number (in another programming lang) by XOR-ing the number with 0xFF:
$p = 7; $n = $p ^ 0xFFFF_FFFF; # im on 32-bit winxp system printf "%x", $n; # FFFFFFF8
So, im confused, what's right?

Replies are listed 'Best First'.
Re: Negating a number
by almut (Canon) on Mar 04, 2009 at 17:49 UTC

    See One's complement vs. Two's complement.  One's complement representation is symmetric (same max. positive and negative value) and has a negative zero; the negative counterpart of a positive value can be obtained by bitwise negating (the XOR you mentioned) the positive value (and the other way round, of course).  Two's complement representation (Perl's native signed int representation), in contrast, doesn't have a negative zero, but one more value on the negative side (e.g. -128..127, for byte size).

Re: Negating a number
by Illuminatus (Curate) on Mar 04, 2009 at 17:24 UTC
    What is right, indeed... Depends on what you are trying to do. Please read 2's compleent. If you are doing ordinary arithmetic, then what you are doing is probably what you want. If you are doing something like calculating a TCP checksum, then the other method is closer to (but not exactly) what you want.
      Illuminatus is going the right direction.
      Your first example yields the binary of negative seven.
      The second example is the negation of the bits of a hex seven.
Re: Negating a number
by repellent (Priest) on Mar 04, 2009 at 17:50 UTC
    It's just terminology. There is a difference between negation and making a number negative.

    Your first example makes $n negative of $p, in a number sense.

    Your second example negates all bits of $p, in a boolean sense, complementing/flipping the bits 1 -> 0 and 0 -> 1.
Re: Negating a number
by holli (Abbot) on Mar 04, 2009 at 17:24 UTC
    $x = $x * (-1); or $x *= -1;


    holli

    When you're up to your ass in alligators, it's difficult to remember that your original purpose was to drain the swamp.
Re: Negating a number
by kennethk (Abbot) on Mar 04, 2009 at 17:29 UTC
    A consequence of Perl's weak typing is that TIMTOWTDI applies equally well to negation of numbers. Since the XOR approach relies on the numerical model and current state of your variable, it is likely to be less portable and so is less desirable. See perldata for some info on what constitutes a "number" in Perl.

    And if your numerical operations need to squeeze out every bit of computational efficiency, you probably shouldn't be using Perl.