I'm reminded of a math puzzle that goes thusly:
Two mathematicians find themselves in that terrible kingdom where the king kills them unless they perform some mundane logical task. Don't move there, it's awful.
Our heroes must flip a coin each day, and at least one of them must guess correctly the other guy's coin or they both die. Naturally, they are able to live forever using one little trick (executioners hate them!)
What do they do? Well, they have one guy always guess whatever he flips, and the other guy always guess what he didn't flip. So if they end up flipping the same thing, the guy who guesses same will be correct. If they end up flipping different, the other guy will be correct.
I'm going to employ the logic used to solve this puzzle to solve our puzzle here.
Basically, we're going to use the most significant bit in the integer to store whether or not we need to flip signs. It's possible that any bit would do, but the MSB is the least damaging to the number of we end up having to sacrifice it. I'm pretty sure we don't, but I can't rule it out.
Let us say that A
is our most significant bit, and S
is our sign bit. The remaining bits determine the magnitude of N (As I said, I have not yet concluded if the A
bit can be included in the magnitude, or if we have to sacrifice that bit's "usefulness" towards the magnitude in order to serve as data storage about the stage of the operation).
This gives 4 kinds of numbers:
S A
0 0 : N is a "small" positive number, perhaps 0.
0 1 : N is a "large" positive number
1 1 : N is a "small" negative number, perhaps -1
1 0 : N is a "large" negative number
For any number x (positive or negative), negating that number generally flips both the S bit and the A bit -- except for the special values 0 and "the weird number".
We can do this with any number of bits, so for this example we'll use 8 bit numbers.
Our 8 bit number will be 53, or 0b 0011 0101
. Our mission will be to turn this into -53, or 1100 1011
Now since we're using 1 bit for sign, and 1 bit for our own purposes, the range this function holds for is only 6 bits (unless it actually DOES hold for all 7 bits, I just haven't tested that condition).
The function operates thusly:
if A == S, flip A.
else flip A and then multiply by the value negative 1.
So F(0b 0011 0101) = 0b 0111 0101
. When we pass this through the function again, A
will no longer equal S
. So it hits the else clause, flipping the A
bit (back to 53) and multiplying by negative 1.
Another example, starting with -53 == 0b 1100 1011
:
F(0b 1100 1011) == 0b 1000 1011
Then F(0b 1000 1011)
hits the else clause, flipping the A bit to get 0b 1100 1011
== -53, and then negating the number to get +53 == 0b 0011 0101
.
So the idea is that we're sacrificing the A
bit for the purposes of F(x)
because it should get reversed when we run the result through F
again. Note that F(x)
by itself is not a particularly useful function. Also that this may not work for edge cases (I haven't tested much. 0, MAX_VALUE, MIN_VALUE, and -1 all come to mind as cases to test.)
-n
as~n
(that is,n
with all bits flipped). As with sign-magnitude it has both a positive and a negative representation of zero. – Steve Jessop Apr 28 '14 at 16:40