Java数据结构和算法:位运算
位運算因為是CPU直接支持的操作指令,也是基于二進制的操作,所以具有相當高的效率,在一些場合,合理應用位運算將具有很高的性能。通常在一些加密算法,圖型算法中都會使用到位運算。
移位運算符
| << | 左移運算符,將運算符左邊的對象向左移動運算符右邊指定的位數(在低位補0) | x<<3 |
| >> | “有符號”右移運算 符,將運算符左邊的對象向右移動運算符右邊指定的位數。使用符號擴展機制,也就是說,如果值為正,則在高位補0,如果值為負,則在高位補1. | x>>3 |
| >>> | “無符號”右移運算 符,將運算符左邊的對象向右移動運算符右邊指定的位數。采用0擴展機制,也就是說,無論值的正負,都在高位補0. | x>>>3 |
對于java移位運算的總結
對于左移運算,每左移一個位,高階位都被移出(并且丟棄),并用0填充右邊。這意味著當左移的運算數是int 類型時,每移動1位,它的第31位就要被移出并且丟棄;當左移的運算數是long 類型時,每移動1位它的第63位就要被移出并且丟棄。
左移都可以使原來的操作數翻倍,程序員們經常使用這個辦法來進行快速的2 的乘法。但是你要小心,如果你將1移進高階位(31或63位),那么該值將變為負值。
在對byte 和short類型的值進行移位運算時 , Java將自動把這些類型擴大為 int 型,而且,移位后的值也是int 型;如果左移不超過31位,原來對應各位的值不會丟棄。但是,如果你對一個負的byte 或者short類型的值進行移位運算,它被擴大為int 型后,它的符號也被擴展,結果的高位就會被1填充。因此,為了得到正確的結果,你就要舍棄得到結果的高位。這樣做的最簡單辦法是將移位運算的結果再轉換成byte 型 。
每右移一次,就相當于將該值除以2并且舍棄了余數。你可以利用這個特點將一個整數進行快速的2的除法。當然,你一定要確保你不會將該數原有的任何一位移出。
無符號右移(>>>)與右移的區別:
每一次右移,>>運算符總是自動地用它的先前最高位的內容補它的最高位。這樣做保留了原值的符號
無符號移動總是在高位(最左邊)補0。
與C、C++不同,Java中沒有無符號型整數,而且明確規定了整型和浮點型數據所占的內存字節數,這樣就保證了安全性、魯棒性和平臺無關性。
roundUpToPowerOfTwo(int i)
獲取大于等于 某個整數 并且是 2 的冪數的整數
public static int roundUpToPowerOfTwo(int i) {i--; // If input is a power of two, shift its high-order bit right.// "Smear" the high-order bit all the way to the right.i |= i >>> 1;i |= i >>> 2;i |= i >>> 4;i |= i >>> 8;i |= i >>> 16;return i + 1; }可以看到這個算法進行了 5 次移位操作,乍一看,一臉懵逼,這是在干嘛?
細細一想啊,我現在要獲取一個是 2 的冪數的整數,那其二進制的表現形式就是其最高位為1 ,低位全部為 0;或者其低位全部為 1,只需再對其加 1,即可變成 2 的倍數。
舉個例子:
1000 0000
0100 0000 // 無符號右移一位
1100 0000 // 上面兩個執行或操作的結果
1100 0000
0011 0000 // 無符號右移二位
1111 0000 // 上面兩個執行或操作的結果
1111 0000
0000 1111 // 無符號右移三位
1111 1111 // 上面兩個執行或操作的結果
其實我們只需將我們的關注點放置其元素為1的最高位上,執行右移操作,緊接著是或操作,最后的結果就是將高位的1,向后涂抹 (smear),全部變為1。
移位5次的原因在于 Java 中的整數是32位的,正好是2的 5次方。
算法剛開始的減一操作,則是為了防止剛開始傳入的數字便是 2 的冪數。用來保證最終的結果是大于等于傳入的參數的值。
總結
以上是生活随笔為你收集整理的Java数据结构和算法:位运算的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 详细介绍Java和C++区别
- 下一篇: java美元兑换,(Java实现) 美元