劍指offer用位運算實現兩個數相加,及python相關的位操作


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

代碼:

# -*- coding:utf-8 -*-
class Solution:
    def Add(self, num1, num2):
        # write code here
        tsum=(num1^num2)&0xFFFFFFFF#step1:相加但不計進位的結果,因python無位數限制,在此將其限定在32位
        carry=((num1&num2)<<1)&0xFFFFFFFF#step2:求出進位結果,並將其轉成32位
        while(carry):#step3:當有進位時,需要將step1和step2的結果繼續相加,即重復step1和stwp2.
            num1=tsum
            num2=carry
            tsum=(num1^num2)&0xFFFFFFFF#相加但不計進位的結果,並將其轉成32位
            carry=((num1&num2)<<1)&0xFFFFFFFF#求出進位結果,並將其轉成32位
       #直到carry為0,即:直到沒有進位為止。
        #最后返回最終的異或(相加)結果
#注意:8位可以表示的數值范圍在 -128到+127,即(100000000-01111111),第一位是符號位。
#所以32位可以表示的數值范圍在 1000 0000 0000 0000 0000 0000 0000 0000到0x7FFFFFFF,即-2147483648到2147483647,但
#是python沒有位數限制,即不存在最高位溢出,不會將表示負數的最高位‘1’認為是符號位,所以會將1000 0000 0000 0000 0000 0000 0000 0000認為是2147483648。
#因此需要進行越界檢查,將負數進行相應處理: ~(tsum^0xFFFFFFFF)
        return tsum if tsum<=0x7FFFFFFF else~(tsum^0xFFFFFFFF)#python的位運算沒有無符號右移操作,需要越界檢查
    
python相關的位操作 (以下部分轉自原文:https://blog.csdn.net/u013061183/article/details/78525807

由於數值在計算機中的存儲采用的是補碼存儲,所以一般的位運算都是基於補碼進行的。現假設某計算機字長為8位 。


原碼: 正數轉化為2進制,負數第一位取1。 
1 : 0000 0001 
-1 : 1000 0001

反碼: 
正數的原碼不變,負數為原碼符號位不變,其余取反。 
1 : 0000 0001 
-1 : 1111 1110

補碼: 
正數原碼不變,負數為原碼符號位不變,其余的按位取反再加一,故1000 0000可以表示為-128 
1: 0000 0001 
-1 :1111 1111 
在這個鏈接里面有原理的詳盡的解釋:

https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

Python中的按位運算符有:左移運算符(<<),右移運算符(>>),按位與(&),按位或(|),按位翻轉(~)。這些運算符中只有按位翻轉運算符是單目運算符,其他的都是雙目運算符。 
python中的&: 
A&B 
利用A,B的補碼按位與(1&1=1,1&0=0,0&0=0),然后把得到的補碼還原,1&1=1 
python中的|: 
A|B 
利用A,B的補碼按位並(1|1=1,1|0=1,0|0=0),然后把得到的補碼還原。1|0=1 
python中的^: 
A^B 
利用A,B的補碼按位異或(1^1=0,1^0=1,0^0=0,即相同為0,不同為1),然后把得到的補碼還原。1^1=0 
python中的~: 
~A 
A的補碼按位取反(~1=0,~0=1),得到的為補碼,輸出還原結果。~1=-2(因為1的補碼為0000 0001,按位取反為1111 1110 這個是-2的補碼) 
python中的>>: 
A>>n 
A的補碼按位向右移動n位,左邊缺少的地方補符號位(即正數補0,負數補1)(相當於除以2的n次方取整 -8>>1=-8//2=-4 -8>>2=-8//4=-2) 
python中的<<: 
B<< n 
B的補碼按位向做移動n位,右邊缺少的補0(相當於乘以2 ,4<<1=4*2=8,4<<2=4*4=16) 
注意:python的<<,與c和java中的不一樣,因為他們有字符長度,8位,16位,32位,所以32位為例,如果1<<31=-2147483648,1<<32=0,因為高位溢出,但是在python中1<<31=2147483648,1<<32=4294967296,因為在python中整數是不限長度的(即不存在高位溢出)



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM