如何考虑Python的负数按位运算?

时间:2020-03-07 09:14:30

标签: python python-3.x bit-manipulation negative-number

我发现很难考虑Python(和Python3)的无限精度负数和按位运算。它不是32位或64位。可以将左侧的1视为“无限多个”。它不是很明确,这就是为什么有时很难考虑它如何工作的原因。

似乎可行的一种方法是:总是做得更多,例如,如果您要处理具有67位的正整数,那么只需考虑负数具有96位或128的运算就可以了位。这是思考的正确方法吗?规格中是否有任何说明其工作方式或应该考虑的内容? (例如内部实现只考虑了正整数,而只考虑了负数为“在左边还有1位”?)

2 个答案:

答案 0 :(得分:4)

您应该认为它们具有无限多个1位。概括地说,two's complement二进制表示形式具有无限多个1;并非可以根据需要添加更多的1,但是这些1 已经已经成为数字表示方式的一部分。

实际上没有真正存储在内存中的是无数个事实,因此,当您考虑这一点时,应该忽略内存的限制,直到遇到 em>是必须编写实现的人。如果您只是想从概念上理解这一点,则无需考虑诸如备用位之类的事情,而且我认为这样做不一定有帮助。


二进制数代表2的幂的和,例如:

11001 2 = 2 4 + 2 3 + 0 + 0 + 2 0

数字-1由无限的1s序列表示,并向左无限远地延伸:

... 1111 2 = ... + 2 3 + 2 2 + 2 1 + 2 0

这在无穷级数的通常意义上是无稽之谈,但是有充分的理由将结果定义为-1。直观上最吸引人的原因是,按照加法算法将1加1会发生什么:

  ...111111111
+            1
  ――――――――――――
= ...000000000 (result)
  ――――――――――――
  ...11111111  (carry)

在最右边的列中有1 + 1,即2,或二进制形式的10 2 ,因此您写0并在左边的下一列中携带1。然后在该列中,您有一个1加一个进位的1,所以您写0并再携带一个1 ...,依此类推,依次为 ad infinitum 。结果在每个位置都为0。因此,... 11111 2 必须表示为-1,因为我们遵循该算法将1加起来,所以表示为0。

如果这还不能令人满意,则还有其他原因应将... 11111 2 解释为-1的表示形式:

  • 无限和1 + 2 + 4 + 8 + ...是一个几何级数;常数比为r的几何级数的公式为1 /(1-r)。此公式仅在-1
  • 无限和1 + 2 + 4 + 8 + ...实际上确实2-adic norm中收敛为-1。
  • 结果-1也可以通过其他定义获得,包括Euler summationas noted by Wikipedia,它们都是 stable linear 将该和与结果∞或-1相关。

我之所以提到这些,还因为它们暗示某些属性仍然适用于算术。运用通常的算法进行加,减和乘以“无穷大”,可以得出明智的结果,服从于算术的通常性质,如关联性,可交换性和分布性。

答案 1 :(得分:2)

有很多方法可以实现无限精度,但是您应该在此处提出实际情况以获得答案。

我也不认为您不了解左侧无限多个1的概念。 正整数:将未保存的位回退为0,从最低有效位保存所有1位 负整数:将未保存的位回退为1,从最低有效位保存所有0位

当您需要对2个无限精度的对象执行按位运算时,也只需对后备位进行操作。 示例:

-25 ^ -1029
-25 = -1 - 8 - 16: 11100(+infinitely many unsaved 1's beyond these 5 saved bits)
-1029 = -1 - 4 - 1024: 11011111110(+infinitely many unsaved 1's beyond these 11 saved bits)
Take XOR, you have to fill more 1's to align the longer one. So it is:
11100111111(+infinitely many unsaved 1's beyond this)
^
11011111110(+infinitely many unsaved 1's beyond this)
=
00111000001(+infinitely many unsaved 0's beyond this)
= 4 + 8 + 16 + 1024 = 1052

从您的问题中我不认为您真的需要有关Python如何实现此目的的技术细节...