位運算符

位運算符

程序設計使用符号
位操作是程序設計中對位模式按位或二進制數的一元和二元操作。 在許多古老的微處理器上, 位運算比加減運算略快, 通常位運算比乘除法運算要快很多。 在現代架構中, 情況并非如此:位運算的運算速度通常與加法運算相同(仍然快于乘法運算)。
  • 中文名:位運算符
  • 外文名:
  • 适用領域:
  • 所屬學科:
  • 用途:程序設計
  • 缺點:隻能為整型和字符型數據
  • 性質:運算符的一種

簡介

位運算符用來對二進制位進行操作,Java中提供了如下表所示的位運算符:位運算符中,除 ~ 以外,其餘均為二元運算符。

位運算符的操作數必須是整數類型,并且遵循尋常算術轉換。

Java使用補碼來表示二進制數,在補碼表示中,最高位為符号位,正數的符号位為0,負數為1。補碼的規定如下:

對正數來說,最高位為0,其餘各位代表數值本身(以二進制表示),如+42的補碼為00101010。

對負數而言,把該數絕對值的補碼按位取反,然後對整個數加1,即得該數的補碼。如-42的補碼為11010110(00101010按位取反11010101+1=11010110)

用補碼來表示數,0的補碼是唯一的,都為00000000。(而在原碼,反碼表示中,+0和-0的表示是不唯一的,可參見相應的書籍)。而且可以用111111表示-1的補碼(這也是補碼與原碼和反碼的區别)。

~ 是一元運算法,對數據的每個二進制位取反,即把1變為0,把0變為1。

C語言的六種

按位與運算

按位與運算符"&"是雙目運算符。 其功能是參與運算的兩數各對應的二進位相與。隻有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。

例如:9&5可寫算式如下: 00001001 (9的二進制補碼)&00000101 (5的二進制補碼) 00000001 (1的二進制補碼)可見9&5=1。 按位與運算通常用來對某些位清0或保留某些位。例如把a 的高八位清 0 , 保留低八位, 可作 a&255 運算 ( 255 的二進制數為11111111)。

按位或運算

按位或運算符“|”是雙目運算符。 其功能是參與運算的兩數各對應的二進位相或。隻要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。

例如:

可寫算式如下:

(十進制為13)可見9|5=13

按位異或運算

按位異或運算符“^”是雙目運算符。 其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。

參與運算數仍以補碼出現。

求反運算

求反運算符~為單目運算符,具有右結合性。 其功能是對參與運算的數的各二進位按位求反。

左移運算

左移運算符“<<”是雙目運算符。左移n位就是乘以2的n次方。 其功能把“<<”左邊的運算數的各二進位全部左移若幹位,由“<<”右邊的數指定移動的位數,高位丢棄,低位補0。

1)例: a<<4 指把a的各二進位向左移動4位。如a=00000011(十進制3),左移4位後為00110000(十進制48)。

2)例: int i = 1; i = i << 2; //把i裡的值左移2位 也就是說,1的2進制是000...0001(這裡1前面0的個數和int的位數有關,32位機器,gcc裡有31個0),左移2位之後變成 000...0100,也就是10進制的4,所以說左移1位相當于乘以2,那麼左移n位就是乘以2的n次方了(有符号數不完全适用,因為左移有可能導緻符号變化,下面解釋原因)

需要注意的一個問題是:int類型最左端的符号位和移位移出去的情況. 我們知道,int是有符号的整形數,最左端的1位是符号位,即0正1負,那麼移位的時候就會出現溢出, 例如: int i = 0x40000000; //16進制的40000000,為2進制的01000000...0000 i = i << 1; 那麼,i在左移1位之後就會變成0x80000000,也就是2進制的100000...0000,符号位被置1,其他位全是0,變成了int類型所能表示的最小值,32位的int這個值是,溢出.如果再接着把i左移1位會出現什麼情況呢?

在C語言中采用了丢棄最高位的處理方法,丢棄了1之後,i的值變成了0. 左移裡一個比較特殊的情況是當左移的位數超過該數值類型的最大位數時,編譯器會用左移的位數去模類型的最大位數,然後按餘數進行移位,如: int i = 1, j = 0x80000000; //設int為32位 i = i << 33; // 33 % 32 = 1 左移1位,i變成2 j = j << 33; // 33 % 32 = 1 左移1位,j變成0,最高位被丢棄 在用gcc編譯這段程序的時候編譯器會給出一個warning,說左移位數>=類型長度.那麼實際上i,j移動的就是1位,也就是33%32後的餘數.在gcc下是這個規則,不同編譯器可能會不完全相同.

總之左移就是: 丢棄最高位,0補最低位。

右移運算

右移運算符“>>”是雙目運算符。右移n位就是除以2的n次方

其功能是把“>>”左邊的運算數的各二進位全部右移若幹位,“>>”右邊的數指定移動的位數。

例如:設 a=15,a>>2 表示把00001111右移為00000011(十進制3)。 應該說明的是,對于有符号數,在右移時,符号位将随同移動。當為正數時, 最高位補0,而為負數時,符号位為1,最高位是補0或是補1 取決于編譯系統的規定。Turbo C和很多系統規定為補1。

右移對符号位的處理和左移不同: 對于有符号整數來說,比如int類型,右移會保持符号位不變。

例如: int i = 0x80000000; i = i >> 1; //i的值不會變成0x40000000,而會變成0xc0000000 就是說,對于有符号數, 符号位向右移動後,正數的話補0,負數補1, 對于有符号數,在右移時,符号位将随同移動: 當為正數時, 最高位補0, 而為負數時,符号位為1, 也就是彙編語言中的算術右移.同樣當移動的位數超過類型的長度時,會取餘數,然後移動餘數個位. 最高位是補0或是補1 取決于編譯系統的規定。Turbo C和很多系統規定為補1。 負數10100110 >>5(假設字長為8位),則得到的是 11111101 總之,在C中,左移是邏輯/算術左移(兩者完全相同),右移是算術右移,會保持符号位不變.實際應用中可以根據情況用左/右移做快速的乘/除運算,這樣會比循環效率高很多。

異或操作的妙用

1. 使特定位翻轉 要使哪幾位翻轉就将與其進行∧運算的該幾位置為1即可。

2 與0相∧,保留原值.

3.交換兩個值,不用臨時變量. 我們可以在不用引入其他變量就可以實現變量值的交換 用異或操作可以實現: a = a^b; //

(1) b = a^b; //

(2) a = a^b; //

(3) 異或操作滿足結合律和交換律,且由異或操作的性質知道,對于任意一個整數a^a=0; 證:(第(2)步中的a) a = a^b =(将第(1)步中的b代入b) a^(a^b) = b; (第(3)步中的b)b =a^b = (将第(1)步中的b代入b,将第(2)步中的a代入a) a^b^a^a^b = a^a^a^b^b = a;

位與運算

清零 A數中為1的位,B中相應位為0。然後使二者進行&運算,即可達到對A清零目的。

取一個數中某些指定位 取數A的某些位,把數B的某些位置1,就把數A的某些位與1按位與即可。

保留一位的方法 數A與數B進行&運算,數B在數A要保留的位1,其餘位為零。

判斷奇偶性 将變量 a的奇偶性。a與1做位與運算,若結果是1,則 a是奇數;将 a與1做位與運算,若結果是0,則 a是偶數。

應用舉例

判斷int型變量a是奇數還是偶數 a&1 = 0 偶數 a&1 = 1 奇數

取int型變量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1

将int型變量a的第k位清0,即a=a&~(1<

将int型變量a的第k位置1, 即a=a|(1<

int型變量循環左移k次,即a=a<>16-k (設sizeof(int)=16)

int型變量a循環右移k次,即a=a>>k|a<<16-k (設sizeof(int)=16)

整數的平均值

對于兩個整數x,y,如果用 (x+y)/2 求平均值,會産生溢出,因為 x+y 可能會大于INT_MAX,但是我們知道它們的平均值是肯定不會绯龅模?頤怯萌缦濾惴ǎ?/DIV> int average(int x, int y) //返回X,Y 的平均值 { return (x&y)+((x^y)>>1); }

判斷一個整數是不是2的幂,對于一個數 x >= 0,判斷他是不是2的幂 boolean power2(int x) { return ((x&(x-1))==0)&&(x!=0); }

不用temp交換兩個整數 void swap(int x , int y) { x ^= y; y ^= x; x ^= y; } php: $a ='dd'; $b = 'bb'; $a = $a ^ $b; $b = $a ^ $b;

$a = $a ^ $b; echo $a,' ', $b; 10 計算絕對值 int abs( int x ) { int y ; y = x >> 31 ; return (x^y)-y ; //or: (x+y)^y }

取模運算轉化成位運算 (在不産生溢出的情況下) a % (2^n) 等價于 a & (2^n - 1) 12 乘法運算轉化成位運算 (在不産生溢出的情況下) a * (2^n) 等價于 a<< n 13. 除法運算轉化成位運算 (在不産生溢出的情況下) a / (2^n) 等價于 a>> n 例: 12/8 == 12>>3 14 . a % 2 等價于 a & 1 15 if (x == a) x= b; else x= a; 等價于 x= a ^ b ^ x;

16 x 的 相反數 表示為 (~x+1)abc

php

位運算符允許對整型數中指定的位進行置位。如果左右參數都是字符串,則位運算符将操作字符的 ASCII 值。

相關詞條

相關搜索

其它詞條