8

Whats the reverse function of x XOR (x/2)?

Is there a system of rules for equation solving, similar to algebra, but with logic operators?

Christian Rau
  • 45,360
  • 10
  • 108
  • 185
fadedbee
  • 42,671
  • 44
  • 178
  • 308

4 Answers4

9

Suppose we have a number x of N bits. You could write this as:

b(N-1) b(N-2) b(N-3) ... b(0)

where b(i) is bit number i in the number (where 0 is the least significant bit).

x / 2 is the same as x shifted left 1 bit. Let's assume unsigned numbers. So:

x / 2 = 0 b(N-1) b(N-2) ... b(1)

Now we XOR x with x / 2:

x ^ (x / 2) = b(N-1)^0 b(N-2)^b(N-1) b(N-3)^b(N-2) ... b(0)^b(1)

Note that the rightmost bit (the most significant bit) of this is b(N-1)^0 which is b(N-1). In other words, you can get bit b(N-1) from the result immediately. When you have this bit, you can calculate b(N-2) because the second bit of the result is b(N-2)^b(N-1) and you already know b(N-1). And so on, you can compute all bits b(N-1) to b(0) of the original number x.

Jesper
  • 202,709
  • 46
  • 318
  • 350
  • The "^0" is true IMHO only if x is typed unsigned. With a signed type and sign extension for the division by 2 the things could look more difficult (indeterminable solution?) – jdehaan Mar 08 '12 at 13:00
  • I'm only interested in unsigned ints. – fadedbee Mar 08 '12 at 13:09
  • Does this mean there is no bitwise way of calculating this? – fadedbee Mar 08 '12 at 13:11
  • @jdehaan If the numbers are not unsigned then `x ^ (x / 2)` is not reversible. For example, both inputs 67 and -68 map to the same result 98. So if you get 98 you won't know if the original number was 67 or -68. – Jesper Mar 08 '12 at 14:12
3

I can give you an algorithm in bits:

Assuming you have an array of n bits:

b = [b1 .. bn] // b1-bn are 0 or 1

The original array is:

x0 = b0
x1 = b1 ^ x0
x2 = b2 ^ x1

or in general

x[i] = b[i] ^ x[i-1]
MByD
  • 135,866
  • 28
  • 264
  • 277
1

I know it's an old topic, but I stumbled upon the same question, and I found out a little trick. If you have n bits, instead of requiring n bits operations (like the answer by Jesper), you can do it with log2(n) number operations :

Suppose that y is equal to x XOR (x/2) at the beginning of the program, you can do the following C program :

INPUT : y

int i, x;
x = y;
for (i = 1; i < n; i <<= 1)
    x ^= x >> i;

OUTPUT : x

and here you have the solution.

  • ">>" is the right bit shift operation. For example the number 13, 1101 in binary, if shifted by 1 on the right, will become 110 in binary, thus 13 >> 1 = 6. x >> i is equivalent to x / 2^i (division in the integers, of course)
  • "<<" is the left bit shift operation (i <<= 1 is equivalent to i *= 2)

Why does it work ? Let's take as example n = 5 bits, and start with y = b4 b3 b2 b1 b0 (in binary : in the following x is written in binary also, but i is written in decimal)

  • Initialisation :

x = b4 b3 b2 b1 b0

  • First step : i = 1

x >> 1 = b4 b3 b2 b1 so we have x = b4 b3 b2 b1 b0 XOR b3 b2 b1 b0 = b4 (b3^b4) (b2^b3) (b1^b2) (b0^b1)

  • Second step : i = 2

x >> 2 = b4 (b3^b4) (b2^b3) so we have x = b4 (b3^b4) (b2^b3) (b1^b2) (b0^b1) XOR b4 (b3^b4) (b2^b3) = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3)

  • Third step : i = 4

x >> 4 = b4 so we have x = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3) XOR b4 = b4 (b3^b4) (b2^b3^b4) (b1^b2^b3^b4) (b0^b1^b2^b3^b4)

  • Then i = 8, which is more than 5, we exit the loop.

And we have the desired output.

The loop has log2(n) iterations because i starts at 1 and is multiplied by 2 at each step, so for i to reach n, we have to do it log2(n) times.

Yann
  • 31
  • 2
1

Assume Y = X ^ (X / 2)

If you want to find X, do this

X = 0

do

  X ^= Y
  Y /= 2

while Y != 0

I hope it helps!

guga
  • 714
  • 1
  • 5
  • 15