分享本文,希望能起到拋磚引玉的作用,加深朋友對位運(yùn)算以及計(jì)算機(jī)底層的認(rèn)識(shí)。
有如下十進(jìn)制的加法運(yùn)算:
13 + 9 = 22
我們像這樣來拆分這個(gè)運(yùn)算過程:
不考慮進(jìn)位,分別對各位數(shù)進(jìn)行相加,結(jié)果為sum:
個(gè)位數(shù)3加上9為2;十位數(shù)1加上0為1;最終結(jié)果為12;
只考慮進(jìn)位,結(jié)果為carry:
3 + 9 有進(jìn)位,進(jìn)位的值為10;
如果步驟2所得進(jìn)位結(jié)果carry不為0,對步驟1所得sum,步驟2所得carry重復(fù)步驟1、 2、3;如果carry為0則結(jié)束,最終結(jié)果為步驟1所得sum:
這里即是對sum = 12 和carry = 10重復(fù)以上三個(gè)步驟,(a) 不考慮進(jìn)位,分別對各位數(shù)進(jìn)行相加:sum = 22; (b) 只考慮進(jìn)位: 上一步?jīng)]有進(jìn)位,所以carry = 0;(c) 步驟2carry = 0,結(jié)束,結(jié)果為sum = 22。
把上面的運(yùn)算過程放在二進(jìn)制中試試。
13和9的二進(jìn)制分別為:
0000 11010000 1001
①不考慮進(jìn)位,分別對各位數(shù)進(jìn)行相加得到sum:?
0000 0100
②當(dāng)考慮進(jìn)位,有兩處進(jìn)位,第0位和第3位,只考慮進(jìn)位的結(jié)果為carry:
0001 0010
③判斷carry是否為0,為0則結(jié)束,最終計(jì)算結(jié)果為sum;如果carry不為0,則進(jìn)行如下操作,并重復(fù)步驟①②③:
sum+=carry
上面步驟③中判斷carry不為0,回到步驟①:
不考慮進(jìn)位,sum+carry= :
0001 0110
步驟②:
只考慮進(jìn)位,carry =:
0
步驟③:
判斷carry為0,結(jié)束,最終sum=:
0001 0110
轉(zhuǎn)換成十進(jìn)制剛好是22,十進(jìn)制的算法同樣適用于二進(jìn)制!
仔細(xì)觀察發(fā)現(xiàn):
第①步不考慮進(jìn)位的加法其實(shí)就是異或運(yùn)算
第②步只考慮進(jìn)位就是按位與運(yùn)算之后左移一位
第③步就是重復(fù)前面兩步操作,直到第二步進(jìn)位結(jié)果為0
這里為什么要循環(huán)步驟①②③,直到步驟②所得進(jìn)位carry等于0呢?這是因?yàn)橛械臄?shù)做加法時(shí)會(huì)出現(xiàn)連續(xù)進(jìn)位的情況。在第③步檢測carry如果為0,則表示沒有進(jìn)位了,此時(shí),此次循環(huán)第①步的sum即為最終的結(jié)果。
通過位運(yùn)算實(shí)現(xiàn)加法
按照上面的分析,寫出通過位運(yùn)算實(shí)現(xiàn)加法的如下代碼:
// 遞歸寫法 int add(int num1, int num2){if(num2 == 0) return num1;int sum = num1 ^ num2;int carry = (num1 & num2) 《《 1;return add(sum, carry);}
// 迭代寫法 int add(int num1, int num2){ int sum = num1 ^ num2; int carry = (num1 & num2) 《《 1; while(carry != 0){ int a = sum; int b = carry; sum = a ^ b; carry = (a & b) 《《 1; }return sum;}
編輯:lyn
-
C語言
+關(guān)注
關(guān)注
180文章
7608瀏覽量
137150 -
位運(yùn)算
+關(guān)注
關(guān)注
0文章
17瀏覽量
8440
原文標(biāo)題:通過C語言的位運(yùn)算實(shí)現(xiàn)加法操作
文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論