Python整数自动转化为大数的坑

昨天LeetCode随便找了一题准备日常开刷,题目是371.两整数之和。题目大概要求是这样的:不使用+和-的情况下,实现两个整数的加法运算操作。有兴趣请自行移步LeetCode查看这个题。

了解过计算机底层原理的应该知道,目前多数计算机是基于二进制,对十进制数字不能直接利用。即便是整体使用了二进制,但计算机利用其位操作确实实现了十进制的计算,所以算法上可以用类似的原理进行模拟实现这题的需求。原理核心主要是:异或负责表示该位运算结果,两个数相与后左移一位负责表示进位。当进位出现0之后就停止运算,输出这时异或的值。
开始没想太多,python写出来大概就4行左右,脚本运行后发现做运算的两个数在同符号的情况下没有问题,一旦两个数字是异号的时候,程序就陷入了无限循环。

while b:
    a, b = a ^ b, (a & b) << 1
    return a

然后用打印输出的方式查看,发现数字已经十分庞大,然而还在翻倍变化,没有停下来。
随后思考了一番,想到了python数字的特点,声明的时候没有类型的定义,小数和整数有时候运算比较模糊,重要的是一个整数超过表示范围之后是可以变长的,变成大数运算,不会发生整数溢出。因为这个特性,所以数字位数不断增多,按照算法设计想要在最后异或出0是个难事。自动转化这个现象很好验证,int表示范围内高次方或者大范围阶乘这样的大数运算,可以看得出来这个特性。

既然数字都是按照补码来的,可以通过与运算的方式人为地制造溢出,舍弃过大的那一部分。拿64位的python来说,每次异或运算或者与运算之后再和0xFFFFFFFF做一次与运算,从而保证数据的长度。最后注意一下数的大小,如果结果大于0x7FFFFFFF,溢出了,还要和0xFFFFFFFF异或之后取反。

最后通过的代码:

class Solution:
    def getSum(self, a, b):
        """
        :type a: int
        :type b: int
        :rtype: int
        """
        while b:
            a, b = (a ^ b) & 0xFFFFFFFF, ((a & b) << 1) & 0xFFFFFFFF
        if a> 0x7FFFFFFF:
            a = ~(a ^ 0xFFFFFFFF)
        return a

位运算要慎重,位运算要慎重,位运算要慎重!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章