不用 實現加法運算

2021-10-11 08:36:09 字數 1518 閱讀 2385

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

示例:

輸入: a = 1, b = 1

輸出: 2

a, b 均可能是負數或 0

結果不會溢位 32 位整數

我覺得寫這個題一定要對原反補碼的機制非常熟悉,其實加減乘除本身就是我們人自己的思維,在硬體底層笨豬cpu是沒有這麼複雜的想法的,首先cpu只有加法,移位和取反三個法則,而計算機底層都是用補碼來進行運算的,為什麼是補碼呢?

以減法為例:你可以任意舉例,因為我說過cpu沒有設計專門的減法運算邏輯電路,因而我寫成+負數的形式,原碼+(-原碼)一定是不對的,反碼+(-反碼)部分是正確的,而補碼+(-補碼)一定是正確的,所以這也是計算機底層採用補碼運算的原因。

其次補碼中的補是什麼概念?差不多就是互補吧,最經典的就是時鐘的例子,把時鐘從10點調到6點,要麼向後撥8個小時,要麼向前撥4個小時,你不用擔心這兩種操作實際差了12小時,你只用關心指標現在指的是幾就好,在這摸12的時鐘上8與4互補。因而在摸16的運算中,5-3和5+13是一樣的,因而我想引出乙個很重要的概念:補碼是計算機中用來表示負數,使得負數能夠使用加法器參與加法運算的一種碼。

補碼的求法:只考慮整數的話,正數的補碼就是原碼本身,從我們引申的概念也可以看出它是為了取代負數的,所以沒必要變;負數的補碼,符號位不變按位取反再+1,為什麼這樣求呢?來看:

以-11為例,不考慮符號,11使用二進位制表示是 1011,將1011 逐位求反 得到 0100,因為是逐位求反,1011 +0100 = 1111 ,而1111 + 1 = 10000,發現了什麼?10000是四位2二進位制數的模。為什麼10000是4位二進位制數的模呢?原理也很簡單,4位暫存器最高能表示什麼數?即 (二進位制)1111 = (十進位制) 15 , 15 +1 =16 = (二進位制)10000,後四位暫存器清0,所以模為16。

所以公式:原碼+符號不變原按位取反+1=模

那麼符號不變按位取反+1=模-原 即所謂的補碼

所以,負數符號位不變,其餘逐位求反 +1 只是算出補碼最簡單的方法

但其實這個問題每那麼複雜,我只是看到題突然想到這麼多,扯的太遠了,其實補應該取考慮太多底層硬體的,直接二進位制加法,二進位制加法肯定是一種正確的運算方法,類似於那道列豎式的題,不用加減也罷,0與1 有他們天然的運算法則,即與或非,考慮到這裡的0 1加法其實用異或是最好的,即相同為0 不同為1,異或可以天然的幫助我們實現對應的二進位制位上應該為0還是1,它跟加法的結果很像,但是異或運算兩個二進位制數並沒辦法考慮其中的進製問題。,但是這個結果是有用的,我們可以把它看作是兩位數相加後得出個位,如果我們能再把進製單獨得出乙個二進位製碼,你可以看作是單獨的十位兩個再繼續加起來,嗷嚯,不能用加法,嘻嘻,那就繼續用異或,那麼問題又來了,又沒辦法考慮進製了,那就這樣一直搞唄,直到搞到沒進製,也就是 (a&b)<<1為0 的時候

public

intadd

(int a,

int b)

return a;

}

不用加號完成加法運算(2)

今天乙個小朋友問了我乙個很有意思的問題 不用加號的加法運算 大抵就是說,誒 網上有人不用 就可以實現加法喲 這個問題以前大學的時候玩過,是乙個很有意思的問題。每個人小學的時候,都學過四則運算,但是因為四則運算太簡單了,我們誰也沒有注意過我們學習的四則運算包括術式的寫法有乙個前提,就是 在十進位制中!...

用位運算實現不用加減乘除做加法

1.解題思路 使用位運算實現加法 1 一位加法 普通加法 異或 1 1 0 1 1 0 錯誤 1 0 1 1 0 1 正確 0 1 1 0 1 1 正確 0 0 0 0 0 0 正確 問題 沒有採取進製操作導致運算錯誤 難點 如何解決進製問題?與運算1 1 1 進製 1 0 0 不進製 0 1 0 ...

不用 數字運算子做加法

題目 寫乙個函式,求兩個整數的之和,要求在函式體內不得使用 分析 這又是一道考察發散思維的很有意思的題目。當我們習以為常的東西被限制使用的時候,如何突破常規去思考,就是解決這個問題的關鍵所在。看到的這個題目,我的第一反應是傻眼了,四則運算都不能用,那還能用什麼啊?可是問題總是要解決的,只能開啟思路去...