1. 程式人生 > >[不管怎麽記都記不住的位運算]

[不管怎麽記都記不住的位運算]

很多 一個 右移 png 需要 除法 可能 說明 原來

運算符號

技術分享圖片

運算說明

=== 1. and運算 & ===

and運算通常用於二進制的取位操作,例如一個數 and 1的結果就是取二進制的最末位。這可以用來判斷一個整數的奇偶,二進制的最末位為0表示該數為偶數,最末位為1表示該數為奇數。

相同位的兩個數字都為1,則為1;若有一個不為1,則為0。

00101

11100

(&;或者and)

----------------

00100

=== 2. or運算 | ===

or運算通常用於二進制特定位上的無條件賦值,例如一個數or 1的結果就是把二進制最末位強行變成1。如果需要把二進制最末位變成0,對這個數or 1之後再減一就可以了,其實際意義就是把這個數強行變成最接近的偶數。

相同位只要一個為1即為1。

00101

11100

(|或者or)

----------------

11101

=== 3. xor運算 ^ ===

異或的符號是^。按位異或運算, 對等長二進制模式按位或二進制數的每一位執行邏輯按位異或操作. 操作的結果是如果某位不同則該位為1, 否則該位為0.

xor運算的逆運算是它本身,也就是說兩次異或同一個數最後結果不變,即(a xor b) xor b = a。xor運算可以用於簡單的加密,比如我想對我MM說1314520,但怕別人知道,於是雙方約定拿我的生日19880516作為密鑰。1314520 xor 19880516 = 20665500,我就把20665500告訴MM。MM再次計算20665500 xor 19880516的值,得到1314520。

相同位不同則為1,相同則為0。

00101

11100

(^或者xor)

----------------

11001

運算結果

x <- x # y

y <- x @ y

x <- x @ y

執行了第一句後x變成了x # y。那麽第二句實質就是y <- x # y @ y,由於#和@互為逆運算,那麽此時的y變成了原來的x。第三句中x實際上被賦值為(x # y) @ x,如果#運算具有交換律,那麽賦值後x就變成最初的y了。這三句話的結果是,x和y的位置互換了。

=== 4. not運算 ~ ===

not運算的定義是把內存中的0和1全部取反。使用not運算時要格外小心,你需要註意整數類型有沒有符號。如果not的對象是無符號整數(不能表示負數),那麽得到的值就是它與該類型上界的差,因為無符號類型的數是用00到$FFFF依次表示的。下面的兩個程序(僅語言不同)均返回65435。

如果not的對象是有符號的整數,情況就不一樣了,稍後我們會在“整數類型的儲存”小節中提到。

=== 5. shl運算 << ===

a shl b就表示把a轉為二進制後左移b位(在後面添b個0)。例如100的二進制為1100100,而110010000轉成十進制是400,那麽100 shl 2 = 400。可以看出,a shl b的值實際上就是a乘以2的b次方,因為在二進制數後添一個0就相當於該數乘以2。

通常認為a shl 1比a * 2更快,因為前者是更底層一些的操作。因此程序中乘以2的操作請盡量用左移一位來代替。

定義一些常量可能會用到shl運算。你可以方便地用1 shl 16 - 1來表示65535。很多算法和數據結構要求數據規模必須是2的冪,此時可以用shl來定義Max_N等常量。

=== 6. shr運算 >> ===

和shl相似,a shr b表示二進制右移b位(去掉末b位),相當於a除以2的b次方(取整)。我們也經常用shr 1來代替div 2,比如二分查找、堆的插入操作等等。想辦法用shr代替除法運算可以使程序效率大大提高。最大公約數的二進制算法用除以2操作來代替慢得出奇的mod運算,效率可以提高60%。

[不管怎麽記都記不住的位運算]