[英]Can someone explain how this leetcode solution works with negative numbers?
This is a solution for leetcode problem 371 , Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
这是leetcode问题371的解决方案,
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
Why we need MOD
and MAX_INT
and what is this part doing? 为什么我们需要
MOD
和MAX_INT
以及这部分在做什么? ~(a & MAX_INT) ^ MAX_INT
def getSum( a, b):
"""
:type a: int
:type b: int
:rtype: int
"""
MOD = 0xFFFFFFFF
MAX_INT = 0x7FFFFFFF
while b != 0:
a, b = (a ^ b) & MOD, ((a & b) << 1) & MOD
return a if a <= MAX_INT else ~(a & MAX_INT) ^ MAX_INT
print getSum4(-4,2)
-2
The reason for MOD
, MAX_INT
and ~(a & MAX_INT) ^ MAX_INT
is to simulate 32-bit integers. MOD
, MAX_INT
和~(a & MAX_INT) ^ MAX_INT
是模拟32位整数。 This is needed because in Python integers are not bounded. 这是必需的,因为在Python中,整数不受限制。
After doing a calculation, & MOD
is used to only keep the 32-bit least significant bits of the result. 在进行计算之后,
& MOD
用于仅保留结果的32位最低有效位。 In systems where integers are only 32-bits, this is effectively what happens; 在整数只有32位的系统中,这实际上就是这样; the extra bits are simply dropped.
额外的位被简单地删除。
The usage of MAX_INT
is to properly deal with what would be an integer overflow with 32-bit integers. MAX_INT
的用法是正确处理32位整数的整数溢出。 If you add 0x40000000
and 0x40000000
, you'll get 0x80000000
, which in Python is just a positive integer. 如果添加
0x40000000
和0x40000000
,则会得到0x80000000
,这在Python中只是一个正整数。 With 32-bit integers, this would be an overflow and the value is equal to -0x80000000
. 对于32位整数,这将是溢出,值等于
-0x80000000
。
The a & MAX_INT
is to remove the most-significant bit, which in 32-bit integers is essentially used as sign. a & MAX_INT
用于删除最高有效位,其中32位整数基本上用作符号。 The ~(...) ^ MAX_INT
is a way to extend the 31-bit number to the number of bits actually used. ~(...) ^ MAX_INT
是一种将31位数扩展到实际使用的位数的方法。 For example, if Python would only use 42 bits, -0x80000000
would be represented as 0xff80000000
. 例如,如果Python只使用42位,则
-0x80000000
将表示为0xff80000000
。 In other words, just set every bit beyond the least significant 31 bits to 1
. 换句话说,只需将每个位超出最低有效31位设置为
1
。 (Doing ~x
is the same as doing x ^ 0xff...ff
, so ~x ^ MAX_INT
is the same as x ^ (0xff..ff MAX_INT)
and x ^ 0xff...ff80000000
and even x | 0xff...ff80000000
if x
"uses" only 31 bits). (做
~x
与做x ^ 0xff...ff
,所以~x ^ MAX_INT
与x ^ (0xff..ff MAX_INT)
和x ^ 0xff...ff80000000
甚至x | 0xff...ff80000000
如果x
“仅使用”31位)。
Of course, Python conceptually doesn't have a fixed number of bits it uses, but you can kind of look at it as if there will be an infinite number of bits set to 1. It just doesn't store all those bits, just like it doesn't store all 0 bits in positive numbers (eg 0x00...001). 当然,Python在概念上没有使用固定数量的位,但你可以看一下它就好像将无限数量的位设置为1.它只是不存储所有这些位,只是比如它不会将所有0位都存储为正数(例如0x00 ... 001)。
An alternative way would be to do ~x ^ MOD
, where you use that the 32nd bit is already correctly set. 另一种方法是做
~x ^ MOD
,你可以使用第32位已经正确设置。
I'm not surprised you're having a hard time trying to understand that code, definitely it works alright but I'd recommend you to start from scratch. 我并不感到惊讶你很难理解代码,但它确实可以正常工作,但我建议你从头开始。 First be sure you master bit operators, integer representation of numbers and two's complement for negative ones.
首先要确保掌握位运算符,数字的整数表示和负数的二进制补码 。 Then just try to understand these 2 simpler functions with a couple of tests:
然后尝试通过几个测试来理解这两个更简单的函数:
def add_32bits_buggy(a, b):
MOD = 0xFFFFFFFF
while (a != 0):
c = (b & a) & MOD
b = (b ^ a) & MOD
a = (c << 1) & MOD
return b
def add_32bits(a, b):
MOD = 0xFFFFFFFF
MAX_INT = 0x7FFFFFFF
while (a != 0):
c = (b & a) & MOD
b = (b ^ a) & MOD
a = (c << 1) & MOD
if b <= MAX_INT:
return b
else:
return ~(b & MAX_INT) ^ MAX_INT
# value to test edge_cases
max_v = 0xFFFFFFFF
# Positive integers
i = 1
while i <= max_v:
i *= 2
a, b = max_v + 1, i
print "{0:10d}\t{1:10d}".format(
add_32bits(a, b), add_32bits_buggy(a, b),
)
print '-'*80
# Negative integers
i = 1
while i <= max_v:
i *= 2
a, b = max_v + 1, i
print "{0:10d}\t{1:10d}".format(
add_32bits(a, -b), add_32bits_buggy(a, -b),
)
The function add_32bits_buggy will answer your question "Why we need MOD
and MAX_INT
and what is this part doing? ~(a & MAX_INT) ^ MAX_INT
". 函数add_32bits_buggy将回答你的问题“为什么我们需要
MOD
和MAX_INT
以及这部分做什么? ~(a & MAX_INT) ^ MAX_INT
”。 Then add_32bits (which is equivalent to your original code) will show how those cases are fixed because of the return. 然后add_32bits(相当于您的原始代码)将显示由于返回而修复这些情况的方式。
Hope it helps. 希望能帮助到你。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.