>>相當於使當前二進位制對應的10進製數除以2.<
例如,a=2,b=9;
a的二進位制數是:0010,如果a左移1位,即a>>1,得到0001,即十進位制數1。b的二進位制數是:1001,如果b右移1位,即b<<1,得到10010,即18。
所以,如果要求兩個數的平均值,可以使用(a+b)>>1,得到0101,即十進位制數5,這裡你會疑問,(2+9)/2=5.5,這裡就是說左移只能對結果是偶數的數值求平均值才能得到正確結果,對應奇數結果的平均值,他會向下取整,所有得到5.5。
某個正整數的負數可以通過~取反後+1來獲得。
假設a=1,求它的負數,即-1的二進位制表示。1的二進位制表示是,0001,-1就是正整數二進位制的反碼加1,即(~1)+1,(1110)+0001=1111,這裡只是使用4位二進位制來表示,當然如果使用8位二進位制表示來計算,可以表示為1的8位二進位制表示,00000001,-1的8位二進位制表示,11111111
&可以用來判斷10進製數的奇偶。
例如,判斷a=10,b=23是奇數還是偶數。a的二進位制數是00001010b的二進位制數是00010111只需要和1進行與操作即可,因為乙個奇數的二進位制表示中1的個數肯定是偶數,而乙個偶數的的二進位制表示中1的個數肯定是奇數個。為零為偶,否則奇數。同a&1和b&1來判斷a和b是奇數還是偶數。00001010&00000001結果是,00000000,所有a是偶數。00010111&00000001結果是,00000001,所有b是奇數。
只需要對兩個數進行異或運算後,如果結果為0則證明相等,否則不相等。
假設a=3,b=4,c=3,判斷a==b,a==c是否成立。a的二進位制,0011b的二進位制,0100c的二進位制,00110011^0100結果為,0111,結果不為零,所以a!=b0011^0011結果為,0000,結果為零,所以a==c
假設現在有兩個數值a=4,b=9,交換這兩個數,只需要執行
a^=b b^=aa^=b
計算過程:
已知a=0100,b=10010100^1001結果:a=1101,b=10011001^1101結果:b=0100,a=11011101^0100結果:a=1001,b=0100
加法運算使用位運算實現加法運算主要分為兩個部分。
假設需要對a,b兩個值進行加法運算,
步驟一,先計算完全不考慮進製進行相加的值,通過異或操作來實現。a = a^b,a即是不考慮進製相加後的值。
步驟二,計算只考慮進製的產生值,通過(a&b)<<1可以得到只考慮進製產生的值,將這個值賦值給b,即b=((a&b)<<1)。如果計算出來的b值不等於0,就說明發生了進製,就需要重複步驟一和步驟二,直到b的值為0。
例子:假設a=12,b=19,通過位運算來實現a+b。a的二進位制數:00001100b的二進位制數:00010011先執行異或操作,算出a+b不考慮進製的情況下,得到的值,什麼叫不考慮進製的值?通過10進製的計算來說明不考慮進製的計算,或許能讓人更容易理解。還是a=13,b=19,計算a+b, 13+19可以看到,個位上3+9=12,是發生了進製的,正常情況下(也就是考慮進製的情況下),需要向十位進1,得到的結果就是32,但是,在不考慮進製的情況下,得到的結果就是22,很明顯,這個22並不是正確的計算結果,我們需要將這個22加上剛才3+9產生的進製值進行相加22+10,才是正確的值。那麼回到二進位制的計算分析過程,00001101^00010011結果是a =00011110,這是二進位制進行不考慮進製情況下得出的結果。再計算他們相加的過程有沒有發生進製,通過(a&b)<<100001101&00010011進行與運算得出的結果是00000001,然後向左移動1位,得到結果是b=00000010,可以看到這個結果不為0,所以它是發生了進製。所以需要重複步驟一和步驟二。下面就不再贅述,只是展示重複步驟的過程第二次00011110^00000010a=00011100b=00000100第三次00011100^00000100a=00011000b=00001000第四次00011000^00001000a=00010000b=00010000第五次00010000^00010000a=00000000b=00100000第六次00000000^00100000a=00100000b=00000000這時候b等於0了,而a=00100000,也就是十進位制的32,所以結果是正確的。
c++**如下://方法一:使用迴圈int bit_add(int a, int b) while (carry != 0); return add;}
c++
輸出結果:
減法運算
實現a – b只要實現a + (-b)即可。所以只要將a和b的相反數呼叫add函式就行。根據二進位制數在機器中表達的規則,得到乙個數的相反數,就是這個數的二進位制數表達取反加1(補碼)的結果。
int bit_subtract(int a, int b)
c++
下面的例子是計算13-19
結果:
乘法運算
用位運算實現乘法運算。a × b的結果可以寫成 a∗2^0∗b_0+a∗2^1∗b_1+…a∗2^i∗b_i+…a∗2^31∗b_31. 其中b_i為0或1表示整數b的二進位制表達中第i位的值(從右往左數)。該過程有點類似於求整數的n次方問題。具體實現參照如下**:
這裡只考慮了正整數相乘的結果。
int multi(int a, int b) return res;}
c++
假設a=12,b=9,計算a*b。a的二進位制數:00001100b的二進位制數:00001001第一遍:通過b&1判斷最後一位是不是1,很明顯b的最後一位是1,所以這個位上是會產生值得,所以b&1的值為,00000001res =00001100a=00011000b=00000100第二遍:b&1的值為,00000000,因為等於零,所以沒有產生數值,所以res不變res =00001100a=00110000b=00000010第三遍:b&1的值為,00000000,因為等於零,所以沒有產生數值,所以res不變res =00001100a=01100000b=00000001第四遍:b&1的值為,00000001, res =01101100a=11000000b=00000000這裡b=0,計算結束,所以最好a*b的值為01101100,即十進位制數108。
除法運算用位運算實現除法運算其實就是乘法的逆運算。定義 res 表示除法的結果。首先將a向右移位31位,然後看能不能容下b,如果能,說明a/2^31可以包含乙個b,等價於a可以包含乙個b∗2^31,令res的第31位為1,此時a的值應該為a−b∗2^31;如果不能容下b,令res的第31位為0,a的值不變;接下來將a向右移位30位是否能容下b……重複步驟直到a−b∗2^i=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,結果記為c<2>計算c∗b<3>計算(a−c∗b)/b,結果記為rest<4>計算c+rest
**實現如下:
**中的int_min在標準標頭檔案limits.h中定義。
#define int_max 2147483647#define int_min (-int_max - 1)在c/c++語言中,不能夠直接使用-2147483648來代替最小負數,因為這不是乙個數字,而是乙個表示式。表示式的意思是對整數21473648取負,但是2147483648已經溢位了int的上限,所以定義為(-int_max -1)。c中int型別是32位的,範圍是-2147483648到2147483647 。 (1)最輕微的上溢是int_max + 1 :結果是 int_min; (2)最嚴重的上溢是int_max + int_max :結果是-2; (3)最輕微的下溢是int_min - 1:結果是是int_max; (4)最嚴重的下溢是int_min + int_min:結果是0
int divide(int a, int b)
c++
位運算只能對整數進行操作。
不多於5位的正整數的處理
open judge問題描述 15 不多於5位的正整數的處理 檢視 提交 統計 提問 總時間限制 1000ms 記憶體限制 65535kb 描述乙個不多於5位的正整數a,要求 1.求出它是幾位數 2.分別打出每一位數字 3.按逆序打出各位數字,例如原數為321,應輸出123。輸入一行,不多於5位的正...
實訓 輸入乙個不多於5位的正整數(C語言)
problem description輸入乙個不多於5位的正整數,程式設計實現以下功能 用兩種方法實現 1 判斷它是幾位數 2 分別列印每一位數字 3 按逆序輸出各位數字 4 例如 輸入2345 5 則輸出 2 3 4 5 5 4 3 2 思路首先用if語句判斷輸入的數是幾位數,然後分別求出每位上的...
C語言程式設計輸入乙個5位數以內的正整數,完成以下操作
1 判斷輸入的數是乙個幾位數 這裡利用乙個簡單的while迴圈即可實現 while x 2 按序或逆序輸出其各位數字 首先使用陣列將數字每一位取出存入陣列for i 0 i suu i 最後利用for迴圈語句將其正反輸出即可 完整源 如下 include includeint main printf...