各种位运算的使用
位運(yùn)算
????程序中的所有數(shù)在計算機(jī)內(nèi)存中都是以二進(jìn)制的形式儲存的。位運(yùn)算說穿了,就是直接對整數(shù)在內(nèi)存中的二進(jìn)制位進(jìn)行操作。比如,and運(yùn)算本來是一個邏輯運(yùn)算符,但整數(shù)與整數(shù)之間也可以進(jìn)行and運(yùn)算。舉個例子,6的二進(jìn)制是110,11的二進(jìn)制是1011,那么6 and 11的結(jié)果就是2,它是二進(jìn)制對應(yīng)位進(jìn)行邏輯運(yùn)算的結(jié)果(0表示False,1表示True,空位都當(dāng)0處理)。
各種位運(yùn)算的使用
=== 1. and運(yùn)算 ===?? &
???and運(yùn)算通常用于二進(jìn)制取位操作,例如一個數(shù) and 1的結(jié)果就是取二進(jìn)制的最末位。這可以用來判斷一個整數(shù)的奇偶,二進(jìn)制的最末位為0表示該數(shù)為偶數(shù),最末位為1表示該數(shù)為奇數(shù).
?? 相同位的兩個數(shù)字都為1,則為1;若有一個不為1,則為0。
static void Main(string[] args){Random ran = new Random();int num = ran.Next();Console.WriteLine(num);if ((num & 1) == 1){Console.WriteLine("this ran is an odd");}else {Console.WriteLine("this ran is an even");}Console.ReadKey();}
=== 2. or運(yùn)算 ===?? |
???? or運(yùn)算通常用于二進(jìn)制特定位上的無條件賦值,例如一個數(shù)or 1的結(jié)果就是把二進(jìn)制最末位強(qiáng)行變成1。如果需要把二進(jìn)制最末位變成0,對這個數(shù)or 1之后再減一就可以了,其實際意義就是把這個數(shù)強(qiáng)行變成最接近的偶數(shù)。
????相同位只要一個為1即為1。
??
????? 或:? 是有真就是真
???? 同或:同真,不同假
???? 異或:同假,不同真
?
=== 3. xor運(yùn)算 ===??? ^
????xor運(yùn)算通常用于對二進(jìn)制的特定一位進(jìn)行取反操作,因為異或可以這樣定義:0和1異或0都不變,異或1則取反。
? xor運(yùn)算的逆運(yùn)算是它本身,也就是說兩次異或同一個數(shù)最后結(jié)果不變,即(a xor b) xor b = a。xor運(yùn)算可以用于簡單的加密,但怕別人知道,于是雙方約定密鑰。我通過程序簡單加密講信息發(fā)給同伙,同伙打開手機(jī)一看:?
??? “xm~kix6\yhcbk,Hizi`c|aibx,Nmbg7,,xeai6>86<<7”
?? 由于我們商定密鑰為12,然后他通過下面程序輸入信息和密鑰進(jìn)行解密:
??
class Param{ private static void addSec(string target,int sec) {//Convert.ToInt32(Encoding.ASCII.GetBytes(target));byte[] b = System.Text.Encoding.UTF8.GetBytes(target);int[] stemp = new int[b.Length];for (int i = 0; i < b.Length; i++){stemp[i] = Convert.ToInt32(b[i]) ^ sec;b[i] = Convert.ToByte(stemp[i]);}Console.WriteLine(System.Text.Encoding.UTF8.GetString(b));}static void Main(string[] args){addSec("xm~kix6\yhcbk,Hizi`c|aibx,Nmbg7,,xeai6>86<<7",12);Console.ReadKey(); }}???于是他就明白了我的真實意思:????????
???????? ?target:Pudong Development Bank;? time:24:00
? ?異或運(yùn)算:相同位不同則為1,相同則為0。
?
=== 4. not運(yùn)算 ===??? ~
not運(yùn)算的定義是把內(nèi)存中的0和1全部取反。使用not運(yùn)算時要格外小心,你需要注意整數(shù)類型有沒有符號。如果not的對象是無符號整數(shù)(不能表示負(fù)數(shù)),那么得到的值就是它與該類型上界的差,因為無符號類型的數(shù)是用00到$FFFF依次表示的。
?
=== 5. shl運(yùn)算 ===?????? <<
a shl b就表示把a(bǔ)轉(zhuǎn)為二進(jìn)制后左移b位(在后面添b個0)。可以看出,a shl b的值實際上就是a乘以2的b次方,因為在二進(jìn)制數(shù)后添一個0就相當(dāng)于該數(shù)乘以2。
X<<1=x*2;
X<<2=x*4;
X<<3=x*8;
…….
通常認(rèn)為a shl 1比a * 2更快,因為前者是更底層一些的操作。想辦法用shl代替除法運(yùn)算可以使程序效率提高。你可以方便地用1 shl 16 - 1來表示65535。很多算法和數(shù)據(jù)結(jié)構(gòu)要求數(shù)據(jù)規(guī)模必須是2的冪,此時可以用shl來定義Max_N等常量。
?
=== 6. shr運(yùn)算 ===
和shl相似,a shr b表示二進(jìn)制右移b位(去掉末b位),相當(dāng)于a除以2的b次方(取整)。我們也經(jīng)常用shr 1來代替div 2,比如二分查找、堆的插入操作等等。想辦法用shr代替除法運(yùn)算可以使程序效率大大提高。最大公約數(shù)的二進(jìn)制算法用除以2操作來代替慢得出奇的mod運(yùn)算,效率可以提高60%。
x>>1=x/2;
x>>2=x/4;
x>>3=x/8;
….
?
常見位操作:
????去掉最后一位 x shr 1 在最后加一個0 x shl 1 在最后加一個1 x shl 1+1 把最后一位變成1 x or 1 把最后一位變成0 x or 1-1 最后一位取反? ?x xor 1 把右數(shù)第k位變成1? x or (1 shl (k-1)) 把右數(shù)第k位變成0? x and not (1 shl (k-1)) 右數(shù)第k位取反 x xor (1 shl (k-1)) 取末三位? x and 7 取末k位 x and (1 shl k-1) 取右數(shù)第k位 x shr (k-1) and 1 把末k位變成1 x or (1 shl k-1) 末k位取反? x xor (1 shl k-1) 把右邊連續(xù)的1變成0? x and (x+1) 把右起第一個0變成1? x or (x+1) 把右邊連續(xù)的0變成1? x or (x-1) 取右邊連續(xù)的1? (x xor (x+1)) shr 1 去掉右起第一個1的左邊? x and (x xor (x-1))總結(jié)
- 上一篇: RAC 学习笔记RAC 学习笔记(1)-
- 下一篇: JAVA面向对象编程(2)