鉴于XOR&两个数的和。如何找到这些数字? 例如,x = a + b,y = a ^ b;如果给出x,y,如何获得a,b? 如果不能,请说出原因。
答案 0 :(得分:9)
这不能可靠地完成。 单个反例也足以破坏任何理论,在您的情况下,该示例为0, 100
和4, 96
。这两者总和为100
和xor至100
:
0 = 0000 0000 4 = 0000 0100
100 = 0110 0100 96 = 0110 0000
---- ---- ---- ----
xor 0110 0100 = 100 xor 0110 0100 = 100
因此,给定100
和100
的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的每个位,您可以选择a
或b
中哪一个贡献该位。显然,这个子集并没有覆盖整个输入,但它至少证明了它无法完成。
此外,存在许多(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这个等式可能对你有用