因為計算機的運算模式是以二進位制為基礎,所以十進位制運算在計算時會被轉換成二進位制再進行運算,而轉換過程就會導致執行速度降
低。所以運用位運算可以提高**執行的效率。
位運算說穿了,就是直接對整數在記憶體中的二進位制位進行操作。
注意,位運算只針對於整數進行操作。
二、位運算的使用規則
位運算的使用方法可以網上搜尋,各種各樣的不同角度解釋都有。這裡只進行簡單的規則介紹。附上菜鳥教程鏈結。
符號描述規則&
與全1為1,有0則0|或
有1則1,全0為0^異或
「同」為0,」不同「為1~取反
1變0, 0變1
>>
右移二進位制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
<<
左移二進位制位全部左移若干位(左邊的二進位制位丟棄,右邊補0)。
下面是具體規則的使用。
/*與*/0&
0=0;
0&1=
0;1&
0=0;
1&1=
1;/*或*/0|
0=0;
0|1=
1;1|
0=1;
1|1=
1;/*異或*/0^
0=0;
0^1=
1;1^
0=1;
1^1=
0;/*取反*/~1
=0;~
0=1;
/*左移*/a(
60)=0011
1100
a<<
20011
1100
=>
1111
0000
↑ ↑
高位 低位
溢位 不夠
捨棄 補0
/*右移*/a(
60)=0011
1100
a>>
20011
1100
=>
0000
1111
↑ ↑
正數 低位
高位 直接
補0 捨棄
b(-37)=
1101
1011
b>>
21101
1011
=>
1111
0110
↑ ↑
負數 低位
高位 直接
補1 捨棄
##三、常用舉例
位運算是通過二進位制來表示的,所以只需要通過移動1就可以得到2的n次方的值。如:2^5 = 32
1
<<
50000
0001
<<5=
0010
0000
=32
模擬2的n次方,乘或除以2就是左或右移1。如:16 / 2 = 8 ;4 * 2 = 8
16/2
=80001
0000
>>1=
0000
1000=8
4*2=
80000
0100
<<1=
0000
1000
=8
因為2的次方用二進位制來表示會成為1000…的形式,所以也可以通過按位與運算來進行取餘,因為凡是後面不為0的為對應的都是餘
數。如:9%4 = 9&3
9%4
=10000
1001
90000
00113--
-------
0000
0001
1
n&((1<
因為在計算機中,負數是用補碼表示的,所以如果這個數是負數,對這個數取反+1,就相當於還原了他的原碼,也就是求出了這個
負數的絕對值。所以對於乙個負數n,利用~a+1就可以得到他的絕對值。
對於任何數,異或0會保持不變,異或1會改變,而上面判斷正負得到的是0和-1(也就是全0和全1),這樣的話再通過位運算來簡化一
下,將m設為n>>31(得到n的符號),然後用n^m,這樣就能保證正數不變,負數改變。然後再來處理後面的+1,我們已經知道正數m
為0,負數m為1,所以再在後面減去乙個m就可以得到乙個求絕對值的通式了
負數: b =
~b+1
;通式:
m=n>>31;
return
((n^m)
-m);-12
0000
1100
121111
0100-12
1111
1111-1
----
----
- 異或
0000
1011
11
在計算機中,對於int型的最大值,也就是符號位為0,其餘位賦值為1,這樣直接(1<<31)-1就可以得到。同樣的,對於int型的最小
值,也就是符號位為1,其餘位賦值為0,這樣用(1<<31)直接可以得到答案。
(
1<<31)
-1;//int的最大值(1
<<31)
;//int的最小值
二進位制最後一位決定了數字的奇偶性,直接按位與1就可以判斷出這個數的奇偶性了。
if
(n&1
)else
因為二進位制的第一位為這個數的符號,所以只需要把第乙個數提取出來就可以知道正負了。負數右移完得-1,正數右移完得0。
if
((n>>31)
+1)else
利用負數的補碼表示原則可以輕鬆解決這個問題。
i =
~i +
1;
##四、高階應用
a^
=b;b^
=a;a^
=b;
###2、rgb色彩分離
var 24bitcolor:uint =
0xff00cc
;var r:uint =
24bitcolor >>16;
var g:uint =
24bitcolor >>8&
0xff
;var b:uint =
24bitcolor &
0xff
;
var r:uint =
0xff
;var g:uint =
0x00
;var b:uint =
0xcc
;var 24bitcolor:uint = r <<
16| g <<
8| b;
總結 C 真是博大精深(一)
c 的輸入 輸出和非物件導向的一些特性 最終解釋權歸原文作者所有,侵權必究 1 c 語言是c語言的超集,c語言中的表示式 語句 函式等在c 中仍然可以使用,c 語言是物件導向的語言,但是也包含一些非物件導向的特性。2 include是編譯預處理命令,用於指示編譯器在進行程式預處理時,將檔案iostr...
總結 C 真是博大精深(三)
派生類與繼承 最終解釋權歸原文作者所有,侵權必究 1 繼承是物件導向程式設計的重要特徵之一,通過繼承,可以實現 重用。在c 中,繼承就是利用已有的類,通過派生的方式產生新的類。新類不但繼承了已有類的屬性和方法,而且可以增加新的屬性和方法。2 在c 中,可以在已有類的基礎上構建新類,這個新類繼承了已有...
總結 C 真是博大精深(一)
c 的輸入 輸出和非物件導向的一些特性 最終解釋權歸原文作者所有,侵權必究 1 c 語言是c語言的超集,c語言中的表示式 語句 函式等在c 中仍然可以使用,c 語言是物件導向的語言,但是也包含一些非物件導向的特性。2 include是編譯預處理命令,用於指示編譯器在進行程式預處理時,將檔案iostr...