简体   繁体   English

有人可以解释这个leetcode解决方案如何与负数一起使用?

[英]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? 为什么我们需要MODMAX_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 solution is from this blog 解决方案来自此博客

The reason for MOD , MAX_INT and ~(a & MAX_INT) ^ MAX_INT is to simulate 32-bit integers. MODMAX_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. 如果添加0x400000000x40000000 ,则会得到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_INTx ^ (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将回答你的问题“为什么我们需要MODMAX_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.

相关问题 有人可以解释这个mgiza脚本如何工作吗? - Can someone explain how this mgiza script works? 有人可以解释图像裁剪的工作原理吗? - Can someone explain how image cropping works? 有人可以向我解释这个 leetcode 字符串操作问题吗? - Can someone explain me this leetcode string manipulation question? 有人可以解释一下此代码第二版的工作原理吗? - Can someone please explain how the second version of this code works? 有人可以解释此示例的.extend()深入工作方式吗? - Can someone explain how .extend() works in depth for this example? 有人可以解释 python 中 staticmethod 的源代码是如何工作的吗 - Can someone explain how the source code of staticmethod works in python 请有人解释tkinters文件对话框是如何工作的吗? - Please can someone explain how tkinters file dialog works? 有人可以解释一下这个简短的斐波那契序列代码是如何工作的吗? - Can someone please explain how this short fibonacci sequence code works? 有人可以向我解释这个 for 循环程序是如何工作的吗? - Can someone explain to me how this for-loop program works? 有人可以解释根 function 在这个快速联合实现中是如何工作的吗? - Can someone explain how the root function works in this quick union implementation?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM