C語言 解決不用+、-、×、÷數(shù)字運(yùn)算符做加法的實(shí)現(xiàn)方法
更新時(shí)間:2013年05月24日 09:09:23 作者:
本篇文章是對(duì)在C語言中解決不用+、-、×、÷數(shù)字運(yùn)算符做加法的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
題目:寫一個(gè)函數(shù),求兩個(gè)整數(shù)的之和,要求在函數(shù)體內(nèi)不得使用+、-、×、÷。
分析:這又是一道考察發(fā)散思維的很有意思的題目。當(dāng)我們習(xí)以為常的東西被限制使用的時(shí)候,如何突破常規(guī)去思考,就是解決這個(gè)問題的關(guān)鍵所在。
看到的這個(gè)題目,我的第一反應(yīng)是傻眼了,四則運(yùn)算都不能用,那還能用什么???可是問題總是要解決的,只能打開思路去思考各種可能性。首先我們可以分析人們是如何做十進(jìn)制的加法的,比如是如何得出5+17=22這個(gè)結(jié)果的。實(shí)際上,我們可以分成三步的:第一步只做各位相加不進(jìn)位,此時(shí)相加的結(jié)果是12(個(gè)位數(shù)5和7相加不要進(jìn)位是2,十位數(shù)0和1相加結(jié)果是1);第二步做進(jìn)位,5+7中有進(jìn)位,進(jìn)位的值是10;第三步把前面兩個(gè)結(jié)果加起來,12+10的結(jié)果是22,剛好5+17=22。
前面我們就在想,求兩數(shù)之和四則運(yùn)算都不能用,那還能用什么???對(duì)呀,還能用什么呢?對(duì)數(shù)字做運(yùn)算,除了四則運(yùn)算之外,也就只剩下位運(yùn)算了。位運(yùn)算是針對(duì)二進(jìn)制的,我們也就以二進(jìn)制再來分析一下前面的三步走策略對(duì)二進(jìn)制是不是也管用。
5的二進(jìn)制是101,17的二進(jìn)制10001。還是試著把計(jì)算分成三步:第一步各位相加但不計(jì)進(jìn)位,得到的結(jié)果是10100(最后一位兩個(gè)數(shù)都是1,相加的結(jié)果是二進(jìn)制的10。這一步不計(jì)進(jìn)位,因此結(jié)果仍然是0);第二步記下進(jìn)位。在這個(gè)例子中只在最后一位相加時(shí)產(chǎn)生一個(gè)進(jìn)位,結(jié)果是二進(jìn)制的10;第三步把前兩步的結(jié)果相加,得到的結(jié)果是10110,正好是22。由此可見三步走的策略對(duì)二進(jìn)制也是管用的。
接下來我們?cè)囍讯M(jìn)制上的加法用位運(yùn)算來替代。第一步不考慮進(jìn)位,對(duì)每一位相加。0加0與 1加1的結(jié)果都0,0加1與1加0的結(jié)果都是1。我們可以注意到,這和異或的結(jié)果是一樣的。對(duì)異或而言,0和0、1和1異或的結(jié)果是0,而0和1、1和0的異或結(jié)果是1。接著考慮第二步進(jìn)位,對(duì)0加0、0加1、1加0而言,都不會(huì)產(chǎn)生進(jìn)位,只有1加1時(shí),會(huì)向前產(chǎn)生一個(gè)進(jìn)位。此時(shí)我們可以想象成是兩個(gè)數(shù)先做位與運(yùn)算,然后再向左移動(dòng)一位。只有兩個(gè)數(shù)都是1的時(shí)候,位與得到的結(jié)果是1,其余都是0。第三步把前兩個(gè)步驟的結(jié)果相加。如果我們定義一個(gè)函數(shù)AddWithoutArithmetic,第三步就相當(dāng)于輸入前兩步驟的結(jié)果來遞歸調(diào)用自己。
有了這些分析之后,就不難寫出如下的代碼了:
int AddWithoutArithmetic(int num1, int num2)
{
if(num2 == 0)
return num1;
int sum = num1 ^ num2; //異或運(yùn)算
int carry = (num1 & num2) << 1; //對(duì)0加0、0加1、1加0而言,都不會(huì)產(chǎn)生進(jìn)位,只有1加1時(shí),會(huì)向前產(chǎn)生一個(gè)進(jìn)位。因此兩個(gè)數(shù)先做位與運(yùn)算,然后再向左移動(dòng)一位。
return AddWithoutArithmetic(sum, carry);
}
分析:這又是一道考察發(fā)散思維的很有意思的題目。當(dāng)我們習(xí)以為常的東西被限制使用的時(shí)候,如何突破常規(guī)去思考,就是解決這個(gè)問題的關(guān)鍵所在。
看到的這個(gè)題目,我的第一反應(yīng)是傻眼了,四則運(yùn)算都不能用,那還能用什么???可是問題總是要解決的,只能打開思路去思考各種可能性。首先我們可以分析人們是如何做十進(jìn)制的加法的,比如是如何得出5+17=22這個(gè)結(jié)果的。實(shí)際上,我們可以分成三步的:第一步只做各位相加不進(jìn)位,此時(shí)相加的結(jié)果是12(個(gè)位數(shù)5和7相加不要進(jìn)位是2,十位數(shù)0和1相加結(jié)果是1);第二步做進(jìn)位,5+7中有進(jìn)位,進(jìn)位的值是10;第三步把前面兩個(gè)結(jié)果加起來,12+10的結(jié)果是22,剛好5+17=22。
前面我們就在想,求兩數(shù)之和四則運(yùn)算都不能用,那還能用什么???對(duì)呀,還能用什么呢?對(duì)數(shù)字做運(yùn)算,除了四則運(yùn)算之外,也就只剩下位運(yùn)算了。位運(yùn)算是針對(duì)二進(jìn)制的,我們也就以二進(jìn)制再來分析一下前面的三步走策略對(duì)二進(jìn)制是不是也管用。
5的二進(jìn)制是101,17的二進(jìn)制10001。還是試著把計(jì)算分成三步:第一步各位相加但不計(jì)進(jìn)位,得到的結(jié)果是10100(最后一位兩個(gè)數(shù)都是1,相加的結(jié)果是二進(jìn)制的10。這一步不計(jì)進(jìn)位,因此結(jié)果仍然是0);第二步記下進(jìn)位。在這個(gè)例子中只在最后一位相加時(shí)產(chǎn)生一個(gè)進(jìn)位,結(jié)果是二進(jìn)制的10;第三步把前兩步的結(jié)果相加,得到的結(jié)果是10110,正好是22。由此可見三步走的策略對(duì)二進(jìn)制也是管用的。
接下來我們?cè)囍讯M(jìn)制上的加法用位運(yùn)算來替代。第一步不考慮進(jìn)位,對(duì)每一位相加。0加0與 1加1的結(jié)果都0,0加1與1加0的結(jié)果都是1。我們可以注意到,這和異或的結(jié)果是一樣的。對(duì)異或而言,0和0、1和1異或的結(jié)果是0,而0和1、1和0的異或結(jié)果是1。接著考慮第二步進(jìn)位,對(duì)0加0、0加1、1加0而言,都不會(huì)產(chǎn)生進(jìn)位,只有1加1時(shí),會(huì)向前產(chǎn)生一個(gè)進(jìn)位。此時(shí)我們可以想象成是兩個(gè)數(shù)先做位與運(yùn)算,然后再向左移動(dòng)一位。只有兩個(gè)數(shù)都是1的時(shí)候,位與得到的結(jié)果是1,其余都是0。第三步把前兩個(gè)步驟的結(jié)果相加。如果我們定義一個(gè)函數(shù)AddWithoutArithmetic,第三步就相當(dāng)于輸入前兩步驟的結(jié)果來遞歸調(diào)用自己。
有了這些分析之后,就不難寫出如下的代碼了:
復(fù)制代碼 代碼如下:
int AddWithoutArithmetic(int num1, int num2)
{
if(num2 == 0)
return num1;
int sum = num1 ^ num2; //異或運(yùn)算
int carry = (num1 & num2) << 1; //對(duì)0加0、0加1、1加0而言,都不會(huì)產(chǎn)生進(jìn)位,只有1加1時(shí),會(huì)向前產(chǎn)生一個(gè)進(jìn)位。因此兩個(gè)數(shù)先做位與運(yùn)算,然后再向左移動(dòng)一位。
return AddWithoutArithmetic(sum, carry);
}
相關(guān)文章
C++?IO設(shè)備讀寫功能實(shí)現(xiàn)詳解
C++的文件IO(Input,Output)操作就是指對(duì)文件進(jìn)行讀寫(輸入與輸出)的操作。輸入就是從磁盤上的文件中讀取內(nèi)容到內(nèi)存中。輸出就是將內(nèi)存中的數(shù)據(jù)內(nèi)容輸出或者說寫入到磁盤的文件中,這篇文章主要介紹了C++?IO設(shè)備讀寫功能實(shí)現(xiàn)2022-11-11
C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單的計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01

