Java千問:Java位運算經典應用(一)

不少人認爲位運算在實際開發過程當中並沒什麼用,學習位運算也只是爲了應付面試。這種想法是錯誤的,接下來咱們就經過幾篇連載文章介紹一下位運算在實際開發過程當中的幾個經典應用實例。若是對位運算規則掌握還不是很熟練,能夠先閱讀《Java千問:Java語言位運算符詳解》。這篇文章不只詳細講解了Java位運算的基本規則和一些經常使用的運算定律,同時還在文中提到了一些經常使用的位運算實際應用,好比能夠用位運算操做的方式快速把某個變量所在的內存單元清零,或者位運算的方式實現某個變量快速倍增等等。但文中所這提到的這幾個實際應用比較簡單,本次連載文章將爲你們講述的是更加複雜和實際的應用經典案例。此外,爲得到更好的閱讀效果,請各位讀者在讀本文以前先熟練掌握」補碼」的計算規則。面試

1、判斷整數的奇偶性

按照傳統的思路,判斷一個整數的奇偶性是經過用這個數與2求模,看運算結果是否爲0。學了位運算符之後,咱們能夠換一種思路來考慮問題。咱們知道:Java語言中,全部數字存儲在內存中,都要先轉換成補碼的形式。任何一個偶數用補碼錶示出來後,它的最後一個二進制位都是0,而奇數補碼的最後一個二進制位都是1。因此,咱們能夠經過判斷這個整數的補碼的最後一位二進制數是0仍是1,來判斷這個數是偶數仍是奇數。判斷的方法就是用這個數與1進行按位與的操做,若是結果爲0,那麼這個數就是偶數,不然就是奇數。若是你們不理解這個算法的原理,請看下圖:算法

Java千問:Java位運算經典應用(一)
爲了方便表述,咱們把要判斷奇偶性的數字稱爲a。圖中,以橫線爲界,分別展現了a爲偶數和奇數的狀況下,與數字1進行按位與操做的結果。其中,上面的二進制串是a的補碼,下面二進制串是數字1的補碼。能夠看到,數字1被轉換成補碼以後,總共有32位,其中前31位都是0,最後1位的值是1。這就致使a補碼的前31位不管是0仍是1,與數字1的補碼進行按位與運算,運算結果的前31位都只能是0,決定最終運算結果的就只有a補碼最右邊的那個二進制位。若是最右邊那一位是0,那麼a就是偶數,a與1按位與運算的最終結果是數字0。反過來,若是最右邊那一位是1,那麼a就是奇數,a與1按位與運算的最終結果是數字1。所以咱們只要看一下a與數字1進行按位與運算的結果就知道a的奇偶性了。具體的程序實現以下:編程

Java千問:Java位運算經典應用(一)

2、求絕對值

常規算法求絕對值的思路是:首先判斷一個數a是否>=0,若是a>=0,則返回a自己,不然返回a的相反數。這個過程包含判斷和選擇兩個步驟。若是使用位運算符來實現求絕對值,能夠省略掉判斷的步驟,直接返回運算結果。下面來說解一下使用位運算符求絕對值的基本原理。咱們知道:任何一個二進制位上的數,與0進行異或運算,運算的結果都與這個二進制位上的數相同。把這個結論擴展一下,從原來某個數的單獨的一個二進制位擴展到這個數字自己,能夠得出另外兩個結論,第一個結論:任何一個整數與0進行異或運算後依然保持不變。若是小夥伴不理解的話,請看下圖,咱們以數字5做爲例子分析講解:
Java千問:Java位運算經典應用(一)
另外一個結論:任何一個整數與-1進行異或運算後再加上1,獲得的結果就是這個數的相反數。若是不理解的話,仍是看下圖,仍然是以數字5分析講解:
Java千問:Java位運算經典應用(一)
以上兩個結論中,第一個結論比較容易理解。咱們簡單的解釋一下第二個結論的原理。第二個結論可以成立的關鍵就在於,數字-1用補碼的形式表示出來,剛好是一個32位全爲1的二進制串。這個二進制串與任何一個其餘二進制串進行按位異或運算,均可以達到」取反」的效果,而按照補碼的計算規則,一個正數按位取反後再加1,獲得的就是它相反數。好比圖中的數字5,按位取反以後,再加1獲得的就是-5。
至此,咱們已經知道怎樣經過位運算的方式得到一個數的相反數了。在《Java千問:Java語言位運算符詳解》一文中還講過:int類型的正數通過帶符號右移31位以後,獲得的必然是0,而負數通過帶符號右移31位獲得的是-1。咱們就能夠經過右移所獲得的這個0或者-1,判斷出這個數是正數仍是負數。知道數字的正負屬性,而後再用位運算的方式獲得這個數自己或者是它的相反數,就能求出這個數的絕對值。按照這個思路,咱們就能夠來編寫求絕對值的程序了,程序以下:
Java千問:Java位運算經典應用(一)
示例程序中的變量a是int型,若是改成long型,對a帶符號右移63位也可有相同的運算效果。ide

(未完待續...)
如想系統學習Java編程,歡迎觀看我在本站的視頻課程。學習

相關文章
相關標籤/搜索