劍指向Offer-Python版 -- 不用加減乘除做加法

題目

寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。

# -*- coding:utf-8 -*-
class Solution:
    def Add(self, num1, num2):
        # write code here

題目解析:

要求不使用四則運算符,那麼思路就是位運算,也就是python最底層實現四則運算符的方法

位運算概覽

符號 描述 運算規則
& 兩個位都爲1時,結果才爲1
| 兩個位都爲0時,結果才爲0
^ 異或 兩個位相同爲0,相異爲1
~ 取反 0變1,1變0
<< 左移 各二進位全部左移若干位,高位丟棄,低位補0
>> 右移 各二進位全部右移若干位,對無符號數,高位補0,有符號數,各編譯器處理方法不一樣,有的補符號位(算術右移),有的補0(邏輯右移)

假設num1 =11,num2 = 9

	  11    =>        1011
	+  9    =>    +   1001
	-------        --------
	  20             10100

在位運算中 ^ 和 & 分別產生以下結果

		1011 					  	  1011
	^ 	1001						& 1001
	---------     				------------  
	  	0010						  1001
	  1011  // 
	+ 1001  // 
	---------
	 00010  //1011 ^ 1001 合併得到未進位的結果( 1011 ^ 1001 = 0001010010  // 1011 & 1001 = 1001 不爲 0 存在進位,故執行 1001 << 1 得到進位後的結果 10010 
	---------
	 10000  // 通過 00010 ^ 10010 合併得到未進位的結果( 00010 ^ 10010 = 1000000100  // 00010 & 10010 = 00010 不爲 0 存在進位,故執行 00010 << 1 得到進位後的結果 00100 
	---------
	 10100  // 通過 10000 ^ 00100 合併得到未進位的結果( 10000 ^ 00100 = 1010000000  // 10000 & 00100 = 00000 ,此時結束運算。
	---------
# -*- coding:utf-8 -*-
class Solution:
    def Add(self, num1, num2):
        # write code here
        while num2:
       		# 由於python長整數類型可以表示無限位,所以需要人爲設置邊界,避免死循環。
            result = (num1 ^ num2) & 0xffffffff
            carry = ((num1 & num2) << 1) & 0xffffffff
            num1 = result
            num2 = carry
        if num1 <= 0x7fffffff: # 小於0x7fffffff(max_int) 爲正數
            result = num1
        else:
			"""
			num1 > 0x7fffffff ,則表示 num1二進制下首位爲1  即是負數
			負數是以補碼形式存儲的,python的取反運算結果是補碼。 
			前面用 num1 ^ 0xFFFFFFFF 相當於無視符號位,直接轉爲無符號數,
			此時解釋器已經不認識補碼了。後面再用一次取反,強調是補碼
			"""
            result = ~(num1^0xffffffff) 
        return result

知識補充

在Python內部對整數的處理分爲普通整數和長整數,普通整數長度爲機器位長,通常都是32位,超過這個範圍的整數就自動當長整數處理,而長整數的範圍幾乎完全沒限制所以long類型運算內部使用大數字算法實現,可以做到無長度限制。

每個十六進制數4bit,因此8位16進制是4個字節,剛好是一個int整型
F的二進制碼爲 1111
7的二進制碼爲 0111

這樣一來,整個整數 0x7FFFFFFF 的二進制表示就是除了首位是 0,其餘都是1
就是說,這是最大的整型數 int(因爲第一位是符號位,0 表示他是正數)
同理: 32位的全1數字可爲0xffffffff


參考鏈接:
牛客網
聊聊使用位運算來實現加法(老物)

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