找出b,使a的总和等于xor b

时间:2019-07-19 19:38:28

标签: python

我正在编写采用A 1<A<2*50的代码,找到一个值A+B==A^B

我尝试过,但是对于巨大的价值,解决方案用尽了内存

def solve(A):
   if A==1:
       return 2
   for i in xrange(1,A+1):
        if A+i==A^i:
            return i

预期会获得更大的价值

3 个答案:

答案 0 :(得分:4)

您需要查看XOR的属性。从用于XOR的真值表开始,该表应用于单个位

 A  |  B  |  A ^ B
----|-----|--------
 0  |  0  |    0
 0  |  1  |    1
 1  |  0  |    1
 1  |  1  |    0

将此与A + B

进行比较
 A  |  B  |  A + B
----|-----|--------
 0  |  0  |    0
 0  |  1  |    1
 1  |  0  |    1
 1  |  1  |    10    # requires two bits!

因此,对于A的任何给定位值,B中对应位有2个可能的罗格值1,它们将导致完全相同的结果使用A ^ BA + B。因此,对于A的任何值,B至少有1个值,其中A + B == A ^ B。如果A中的位设置为零(并且B可以超过2 ** 50,则此类位的数量是无限的),那么B会有更多选择。

如果您只需要生成一个数字 ,那么最简单的事情就是让您专注于这些表中的A = 0, B = 1A = 1, B = 0选项。因为如果您将A的值与 only 1进行XOR运算,则您会将A的所有位都变成了完全相反的值,因此创建了为每个B = 1设置A = 0,为每个B = 0设置A = 1

例如,取数字42,它以二进制形式表示为101010(1 x 32、0 x 16、1 x 8、0 x 4、1 x 2和0 x 1,总和为42)。将其与二进制数11111(十进制为63)进行异或,然后翻转所有位:

>>> format(42, '06b')  # 42 in binary, the 6 lower bits
'101010'
>>> 0b111111  # binary number with 6 bits, all 1
63
>>> format(42 ^ 0b111111, '06b')  # XOR with 63, still 6 bits
'010101'
>>> 42 ^ 0b111111  # now in decimal
21

那是您最好的B候选人,将它们加在一起并在这些元素上使用XOR即可得到一个设置了全部6位的数字,因此又是63:

>>> 42 + 21
63
>>> 42 ^ 21
63

您如何知道要使用多少次叮咬?使用int.bit_length() method

>>> (42).bit_length()
6

如何制作一个使用任意数量的位(都设置为1)的整数?通过将2的幂乘以位长,然后减去1:

>>> 2 ** 6
64
>>> 2 ** 6 - 1
63
>>> format(2 ** 6 - 1, 'b')
'111111'

因此解决方案是:

def solve(a):
    return a ^ 2 ** a.bit_length() - 1

这也轻松解决了2 ** 50的问题:

>>> A = 42
>>> B = solve(A)
>>> A + B == A ^ B
True
>>> A = 2 ** 50
>>> B = solve(A)
>>> A + B == A ^ B
True

如果要查看A的所有位置为0的所有位置,则可以为B生成一个 lot 个更多的值。只需从a ^ 2 ** 50 - 1开始,然后获取现在设置为1的每个位(在A中设置为0),并产生将它们设置为0的所有可能组合再次。这些组合中的每一个都是B的另一个有效值。我不会为此生成代码,因为对于A = 2,它包括4到2 ** 50之间的所有整数,因此,除了B之外,还有1.125.899.906.842.621不同的可能值。 B = 1

答案 1 :(得分:0)

让B = A的按位补码。

A + B = 111111111

A xor B = 11111111

答案 2 :(得分:0)

假设给定正整数A,我们想找到满足以下条件的最小正整数B:A + B = A ^ B(A XOR B)

1)对于所有偶数A(2,4,6,8 ...),B = 1 [原因:对于所有偶数,LSB均为0,所以加1将满足我们的条件]

2)对于奇数A,B的幂为2。从2开始检查

------代码段(未测试)------------

def FindB(A):
    if A%2 == 0:
        return 1
    else:
        while True:
            B = 2
            if A+B == A^B:
                return B
            B *= 2