在python中计算两个有符号64位整数之间的异或时出现意外行为

在python中计算两个有符号64位整数之间的异或时出现意外行为,python,bitwise-operators,xor,Python,Bitwise Operators,Xor,我需要计算两个整数之间的汉明距离,通过计算它们的二进制表示之间的不同位数 这是我为此目的使用的功能: def hamming(a, b): # compute and return the Hamming distance between the integers return bin(int(a) ^ int(b)).count("1") 我开始对这个函数进行一些简单的测试,以确保它能正常工作,但我几乎立刻发现它不能正常工作,我正在试图理解为什么 我用这两

我需要计算两个整数之间的汉明距离,通过计算它们的二进制表示之间的不同位数

这是我为此目的使用的功能:

def hamming(a, b):
    # compute and return the Hamming distance between the integers
    return bin(int(a) ^ int(b)).count("1")
我开始对这个函数进行一些简单的测试,以确保它能正常工作,但我几乎立刻发现它不能正常工作,我正在试图理解为什么

我用这两个数字测试了函数:

a = -1704441252336819740
b = -1704441252336819741
python给出的这些数字的二进制表示为:

bin(a): -0b10111 10100111 01100100 01001001 11011010 00001110 11011110 00011100 
bin(b): -0b10111 10100111 01100100 01001001 11011010 00001110 11011110 00011101
正如您所看到的,除了第一个数字之外,它们的二进制表示形式是相同的,因此汉明距离应该是1。 然而,从函数返回的汉明距离是3,我似乎不明白为什么

当我计算这两个数字之间的异或时,会出现问题,因为a^b返回7(因此计数3'1'位),而我希望它返回1(并计数1'1'位)

我相信这与这样一个事实有关,XOR值似乎被存储为一个无符号整数,具有最小的可能位数,而我需要将它存储为


我怎么会误解XOR运算符,怎么才能更改函数以使其按我希望的方式工作?

事实上,误导我的是
bin
函数:
它不显示存储的实际二进制值,而是显示| x |(绝对值),并在其前面打印负号

但是,这不是实际存储值的方式

XOR对存储在中的实际二进制值进行操作,这就是为什么会得到比预期更大的位差

作为一个简单的示例,让我们以两个4位数字为例:

-10 = 0b0110
-11 = 0b0101
  ^ = 0b0011

正如您所看到的,在这种表示法中,这两个数字之间有两个位的差异,而如果它们是正数,则只有一个位的差异。

实际上,是
bin
函数误导:
它不显示存储的实际二进制值,而是显示| x |(绝对值),并在其前面打印负号

但是,这不是实际存储值的方式

XOR对存储在中的实际二进制值进行操作,这就是为什么会得到比预期更大的位差

作为一个简单的示例,让我们以两个4位数字为例:

-10 = 0b0110
-11 = 0b0101
  ^ = 0b0011

如您所见,在这个表示法中,这两个数字之间有两个位的差异,而如果它们是正数,则只有一个位的差异。

好的,因此我的函数工作正常;我只是忘记了2的补码中的整数是如何存储的,这让我相信我的测试失败了,而bin函数的误导性进一步加强了这一点。这听起来正确吗?@LucaGuarro是的,
返回bin(a^b)。只要
a
b
具有相同的符号,计数(“1”)将正常工作。然而,由于
bin
的工作方式,如果一个是正的,另一个是负的,您将得到错误的结果,因为XOR将产生一个负数,而
bin
无法正确翻译。嗯。。。我知道,我应该考虑一种不同的计算汉明距离的方法,因为我可以假设我总是处理64位有符号整数,我可以把所有的负数归一化为正的,通过应用<代码> x=x+2**64 /代码>,对吗?然后安全地按原样使用我的函数,因为数字都是相同的sign@LucaGuarro是的,这会起作用,但前提是64位是您的固定大小。Python实际上将整数存储在一个可以处理任何大小的数字的对象中,但是如果你想在2的恭维中计算负数和正数之间的位差,你必须确定一个固定的长度,以知道负数前面有多少个1;我只是忘记了2的补码中的整数是如何存储的,这让我相信我的测试失败了,而bin函数的误导性进一步加强了这一点。这听起来正确吗?@LucaGuarro是的,
返回bin(a^b)。只要
a
b
具有相同的符号,计数(“1”)将正常工作。然而,由于
bin
的工作方式,如果一个是正的,另一个是负的,您将得到错误的结果,因为XOR将产生一个负数,而
bin
无法正确翻译。嗯。。。我知道,我应该考虑一种不同的计算汉明距离的方法,因为我可以假设我总是处理64位有符号整数,我可以把所有的负数归一化为正的,通过应用<代码> x=x+2**64 /代码>,对吗?然后安全地按原样使用我的函数,因为数字都是相同的sign@LucaGuarro是的,这会起作用,但前提是64位是您的固定大小。Python实际上将整数存储在一个可以处理任何大小的数字的对象中,但是如果您要在2的恭维中计算负数和正数之间的位差,您必须确定一个固定的长度,以知道负数前面有多少个1。