只用位運算不用算術運算實現

2021-09-26 04:47:07 字數 2016 閱讀 1753

題目

給定兩個32位整數a和b,可正、可負、可0.不能使用算術運算子,分別實現a和b的加減乘除。

要求如果給定的a和b執行加減乘除的某些結果本來就會導致資料的溢位,那麼你實現的函式不必對那些結果負責。

基本思路

加法運算

使用位運算實現加法運算主要分為兩個部分。先計算完全不考慮進製進行相加的結果,再計算只考慮進製的產生值。將兩個結果相加就是最終的結果。

例如: 

a:    001010101 

b:    000101111

首先不考慮進製進行相加,結果為001111010,該結果其實就是a ^ b。

再考慮進製的產生值,結果為000001010,該結果其實就是(a & b)<< 1。

將1、2產生的結果再相加,此時依然要考慮兩部分:不考慮進製和只考慮進製。

一直重複上述步驟,直到進製產生的值全部消失。

private int add(int a,int b)

return sum

}

減法運算

實現a - b只要實現a + (-b)即可。所以只要將a和b的相反數呼叫add函式就行。根據二進位制數在機器中表達的規則,得到乙個數的相反數,就是這個數的二進位制數表達取反加1(補碼)的結果

public int negnum(int n)

public int minus(int a,int b)

乘法運算

用位運算實現乘法運算。a × b的結果可以寫成 a∗20∗b0+a∗21∗b1+...a∗2i∗bi+...a∗231∗b31a∗20∗b0+a∗21∗b1+...a∗2i∗bi+...a∗231∗b31. 其中bibi為0或1表示整數b的二進位制表達中第i位的值(從右往左數)。該過程有點類似於求整數的n次方問題。具體實現參照如下**

public int multi(int a,int b)

a <<= 1;

b >>= 1;

}return res;

}

除法運算

用位運算實現除法運算其實就是乘法的逆運算。定義 res 表示除法的結果。首先將a向右移位31位,然後看能不能容下b,如果能,說明a/231a/231可以包含乙個b,等價於a可以包含乙個b∗231b∗231,令res的第31位為1,此時a的值應該為a−b∗231a−b∗231;如果不能容下b,令res的第31位為0,a的值不變;接下來將a向右移位30位是否能容下b……重複步驟直到a−b∗2i=0a−b∗2i=0。 

以上過程只適用於a和b都不是負數的情況下,當a或b為負數時,可以先將a和b轉成正數,計算完之後再判斷res的真實符號就行。 

除法實現到這一步已經可以解決絕大多數情況了。但是我們知道,32位最小整數的絕對值要比最大整數大,所以如果a或b等於最小值,是不能轉換成相對應的正數的。這時候需要分情況考慮:

如果a和b都為最小值,直接返回1

如果a不為最小值,而b為最小值,那麼a/b = 0,直接返回0

如果a為最小值,而b不為最小值。這時我們對a無能為力,但是我們可以讓a增大一點點,計算出乙個結果然後再修正一下就可以得到最終的結果。處理過程如下:

<1>計算(a+1)/b(a+1)/b,結果記為c 

<2>計算c∗bc∗b 

<3>計算(a−c∗b)/b(a−c∗b)/b,結果記為rest 

<4>計算c+rest

public boolean isneg(int n)

public int div(int a,int b)

}return isneg(a)^isneg(b) ? negnum(res):res;

}public int divide(int a,int b)

if (a == integer.min_value && b == integer.min_value)else if (b == integer.min_value)else if (a == integer.min_value)else

}

2 只用位運算不用演算法運算實現整數的加減乘除運算

寫乙個函式,求兩個整數之和,要求在函式體內不得使用 四則運算符號。結論性思路 1.不考慮進製 a b就是正確答案。其中 是異或操作,即相同 0,不同 1 舉例1 0 1 1 二進位制 0000 0001 0001 0 1 1 舉例2 7 5 12 不進製情況下,7 5個位數為2,0111 0101 ...

Python 運算(常用的算術運算 位運算)

運算子含義 例項 假設變數 a 10,b 20 除 x除以y b a 輸出結果 2 取模 返回除法的餘數 b a 輸出結果 0 冪 返回x的y次冪 a b 為10的20次方,輸出結果 取整除 返回商的整數部分 向下取整 9 2 4 運算子含義 按位與操作,只有 1 1 為1,其他情況為0。可用於進製...

不用 實現加法運算

寫乙個函式,求兩個整數之和,要求在函式體內不得使用 四則運算符號。示例 輸入 a 1,b 1 輸出 2a,b 均可能是負數或 0 結果不會溢位 32 位整數 我覺得寫這個題一定要對原反補碼的機制非常熟悉,其實加減乘除本身就是我們人自己的思維,在硬體底層笨豬cpu是沒有這麼複雜的想法的,首先cpu只有...