鉴于XOR&两个数的和。如何找到这些数字?

时间:2013-09-11 03:45:45

标签: math bit-manipulation bitwise-operators bitwise-xor

鉴于XOR&两个数的和。如何找到这些数字? 例如,x = a + b,y = a ^ b;如果给出x,y,如何获得a,b? 如果不能,请说出原因。

4 个答案:

答案 0 :(得分:9)

这不能可靠地完成。 单个反例也足以破坏任何理论,在您的情况下,该示例为0, 1004, 96。这两者总和为100和xor至100

  0 = 0000 0000            4 = 0000 0100
100 = 0110 0100           96 = 0110 0000
      ---- ----                ---- ----
xor   0110 0100 = 100    xor   0110 0100 = 100

因此,给定100100的xor之和,您无法知道可能产生哪种

对于它的价值,该程序只用数字0..255检查可能性:

#include <stdio.h>

static void output (unsigned int a, unsigned int b) {
    printf ("%u:%u = %u %u\n", a+b, a^b, a, b);
}

int main (void) {
    unsigned int limit = 256;
    unsigned int a, b;
    output (0, 0);
    for (b = 1; b != limit; b++)
        output (0, b);
    for (a = 1; a != limit; a++)
        for (b = 1; b != limit; b++)
            output (a, b);
    return 0;
}

然后你可以拿出那个输出并按摩它给你所有重复的可能性:

testprog | sed 's/ =.*$//' | sort | uniq -c | grep -v ' 1 ' | sort -k1 -n -r

给出:

255 255:255
128 383:127
128 319:191
128 287:223
128 271:239
128 263:247
:
and so on.

即使在减少的集合中,也有相当多的组合产生相同的和和xor,最差的是生成255/255的sum / xor的大量可能性,它们是:

255:255 = 0 255
255:255 = 1 254
255:255 = 2 253
255:255 = <n> <255-n>, for n = 3 thru 255 inclusive

答案 1 :(得分:3)

已经证明它无法完成,但这还有两个原因。

对于a和b的(a & b) == 0的(相当大的)子集,你有a + b == (a ^ b)(因为没有进位)(反向含义不成立)。在这种情况下,对于总和为1的每个位,您可以选择ab中哪一个贡献该位。显然,这个子集并没有覆盖整个输入,但它至少证明了它无法完成。

此外,存在许多(x, y)对,例如a + b == x && (a ^ b) == y no 解决方案,例如(不仅仅是这些)所有对{{1}其中(x, y)(即一个是奇数而另一个是偶数),因为xor的最低位和总和相等(最低位没有进位)。通过一个简单的计数参数,这必须意味着至少一些((x ^ y) & 1) == 1必须有多个解决方案:显然所有(x, y)对都有一些与(a, b)相关联的(x, y)对,因此如果不能使用所有(x, y)对,则必须共享其他一对(x, y)

答案 2 :(得分:1)

以下是获得所有此类配对的解决方案

逻辑: 让数字为a和b,我们知道

s = a + b
x = a ^ b

因此

x = (s-b) ^ b

因为我们知道x并且我们知道s,所以对于从0到s的所有整数 - 只需检查是否满足最后一个等式

这是

的代码
public List<Pair<Integer>> pairs(int s, int x) {
    List<Pair<Integer>> pairs = new ArrayList<Pair<Integer>>();
    for (int i = 0; i <= s; i++) {
        int calc = (s - i) ^ i;
        if (calc == x) {
            pairs.add(new Pair<Integer>(i, s - i));
        }
    }
    return pairs;
}

类对定义为

class Pair<T> {
    T a;
    T b;

    public String toString() {
        return a.toString() + "," + b.toString();
    }

    public Pair(T a, T b) {
        this.a = a;
        this.b = b;
    }
}

测试此代码的代码:

public static void main(String[] args) {
    List<Pair<Integer>> pairs = new Test().pairs(100,100);
    for (Pair<Integer> p : pairs) {
        System.out.println(p);
    }
}

输出:

0,100
4,96
32,68
36,64
64,36
68,32
96,4
100,0

答案 3 :(得分:0)

如果你有a,b总和= a + b =(a ^ b)+(a&amp; b)* 2这个等式可能对你有用