我很难将以下功能简化为几个原子二进制操作,感觉有可能但是我无法做到这一点,我已经抓了几个小时了:
public UInt32 reverse_xor_lshift(UInt32 y, Int32 shift)
{
var x = y & (UInt32)((1 << shift) - 1);
for (int i = 0; i < (32 - shift); i++) {
var bit = ((x & (1 << i)) >> i) ^ ((y & (1 << (shift + i))) >> (shift + i));
x |= (UInt32)(bit << (shift + i));
}
return x;
}
该函数的作用就是计算Z = X ^ (X << Y)
的倒数,换句话说reverse_xor_lshift(Z, Y) == X
答案 0 :(得分:4)
通过使用converting back from grey code中使用的相同技术,你可以用更少的操作来反转它,尽管用一种难以理解的方式:
应用转化z ^= z << i
,其中i
从shift
开始,每次迭代加倍。
在伪代码中:
while (i < 32)
x ^= x << i
i *= 2
这是有效的,因为在第一步中,您将最低位(未受影响)放在它们被“xored in”的位置,从而“xoring out out”。然后,已经更改为原始的部分是两倍宽。那么新的数字就是x ^ (x << k) ^ (x << k) ^ (x << 2k) = x ^ (x << 2k)
的形式,它再次是同样的东西,但偏移量是两倍,所以同样的技巧将再次起作用,解码更多的原始位。