Language agnostic 如何使用+;-*/实现XOR?

Language agnostic 如何使用+;-*/实现XOR?,language-agnostic,bit-manipulation,xor,Language Agnostic,Bit Manipulation,Xor,如何仅使用基本算术运算实现异或运算(在两个32位整数上)?你必须在依次除以2的每一次幂后按位计算,还是有捷径?我不在乎执行速度,更在乎最简单、最短的代码 编辑: 这不是家庭作业,而是一个摆在桌子上的谜语。关键是在基于堆栈的虚拟机上实现XOR,操作非常有限(类似于语言和yes-no shift或mod)。使用虚拟机是困难的一部分,当然,通过一个简短而简单的算法会变得更容易 虽然FryGuy的解决方案很聪明,但我必须遵循我最初的理想(类似于litb的解决方案),因为在那种环境下比较也很难使用。很抱歉

如何仅使用基本算术运算实现异或运算(在两个32位整数上)?你必须在依次除以2的每一次幂后按位计算,还是有捷径?我不在乎执行速度,更在乎最简单、最短的代码

编辑: 这不是家庭作业,而是一个摆在桌子上的谜语。关键是在基于堆栈的虚拟机上实现XOR,操作非常有限(类似于语言和yes-no shift或mod)。使用虚拟机是困难的一部分,当然,通过一个简短而简单的算法会变得更容易


虽然FryGuy的解决方案很聪明,但我必须遵循我最初的理想(类似于litb的解决方案),因为在那种环境下比较也很难使用。

很抱歉,我只知道头脑中的直截了当的一个:

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来避免分支。但话说回来,这个解决方案也不是很快,而且看起来很奇怪:)

我不知道这是否违背了你问题的重点,但你可以用and或and实现XOR,如下所示:

uint xor(uint a, uint b) {
   return (a | b) & ~(a & b);
}
在英语中,这是“a或b,但不是a和b”,它精确地映射到XOR的定义


当然,我并没有严格遵守您只使用算术运算符的规定,但至少这是一个简单易懂的重新实现。

如果您有

A或B=A+B-(A和B)

异或B=A+B-2(A和B)


我会用简单的方法:

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;
uint异或(uint a,uint b):
uint-ret=0;
uint事实=0x8000000;
而(事实>0)
{
如果((a>=事实| b>=事实)和&(a=事实)
a-=事实;
如果(b>=事实)
b-=事实;
事实/=2;
}
返回ret;

可能有一种更简单的方法,但我不知道有哪种。

你介意移位和模运算符吗?x听起来像是个家庭作业问题。我一直认为引用任何外部引用都是最好的做法,但是引用你自己关于stackoverflow的问题是相当厚颜无耻的。这是一个多么道德的两难境地。你必须在最后还原结果的各个部分。我在codepad.org上对它进行了测试,结果是:)如果我要做result*=2,我就必须还原;但我使用n来将1比特添加到结果中。因此,我不必在最后恢复是的,我也测试了它,它运行良好,我的坏=)我提出了相同的解决方案+1另一种方法是检查“mod_op(a-b,2)!=0”,但这取决于编程语言的“下溢”行为,所以我最好不要把它放在:)投票,这似乎是最简单的实现。我也喜欢这个。把手放下来,就像我喜欢我的直截了当的方式一样,但你应该得到一个投票:投反对票,嗯?两次?虽然我的回答适用于与OP定义的场景稍有不同的场景,但我认为它仍然提供了有用的辅助信息。我正要问这个问题,这个问题回答了-所以你至少得到了我的支持票。=)
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;