如何仅使用基本算术运算来实现XOR运算(在两个32位整数上)?按顺序除以2的每个幂后,是否必须按位进行,或者是否有快捷方式?关于最简单,最短的代码,我并不关心执行速度。
修改 这不是作业,而是hacker.org上的谜语。重点是在基于堆栈的虚拟机上实现XOR,操作非常有限(类似于brainfuck语言,是 - 没有移位或mod)。使用该VM是困难的部分,尽管通过简短的算法当然可以更容易。
虽然FryGuy的解决方案很聪明,但我必须采用我原来的理想(类似于litb的解决方案),因为在那种环境中比较也很难使用。
答案 0 :(得分:17)
我会用简单的方法做到:
uint xor(uint a, uint b):
uint ret = 0;
uint fact = 0x80000000;
while (fact > 0)
{
if ((a >= fact || b >= fact) && (a < fact || b < fact))
ret += fact;
if (a >= fact)
a -= fact;
if (b >= fact)
b -= fact;
fact /= 2;
}
return ret;
可能有一种更简单的方法,但我不知道。
答案 1 :(得分:11)
我不知道这是否会破坏你的问题,但你可以用AND,OR和NOT来实现XOR,如下所示:
uint xor(uint a, uint b) {
return (a | b) & ~(a & b);
}
在英语中,这是“a或b,但不是a和b”,它精确地映射到XOR的定义。
当然,我并没有严格遵守你只使用算术运算符的规定,但至少这是一个简单易懂的重新实现。
答案 2 :(得分:8)
对不起,我只知道直截了当的人:
uint32_t mod_op(uint32_t a, uint32_t b) {
uint32_t int_div = a / b;
return a - (b * int_div);
}
uint32_t xor_op(uint32_t a, uint32_t b) {
uint32_t n = 1u;
uint32_t result = 0u;
while(a != 0 || b != 0) {
// or just: result += n * mod_op(a - b, 2);
if(mod_op(a, 2) != mod_op(b, 2)) {
result += n;
}
a /= 2;
b /= 2;
n *= 2;
}
return result;
}
可以使用注释中的替代方法而不是if来避免分支。但话说回来,解决方案也不是很快,它让它看起来很奇怪:)
答案 3 :(得分:1)
如果你有AND,那就更容易了
A OR B = A + B - (A和B)
XOR B = A + B - 2(A和B)
int customxor(int a, int b)
{
return a + b - 2*(a & b);
}