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

位運算要慎重,位運算要慎重,位運算要慎重!

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