Android中的位元運算

來源:互聯網
上載者:User

原創文章,如有轉載,請註明出處:http://blog.csdn.net/yihui823/article/details/6754038

其實和java是一樣的,java也通用。

我們人對數位理解,是從十進位開始的。從小受到的教育,也是從 1+9 = 10開始的。但是,對於目前的電腦來說,它們的世界是二進位的世界。電腦用一個高電平表示1,用一個低電平表示0。

如果我們要表示十進位數10,對於電腦來說,必須轉換成位元1010。當然,電腦不但用“0”和“1”來表示資料,還用“0”和“1”來表示字母,表示操作,表示運算,表示推理,表示一切的一切。對於電腦所有操作的原操作,都是“0”和“1”的操作。

對於這些電腦的原操作,也是和我們的認識不同的。我們學的基礎運算,例如1+1=2,那是一個加法而已,是不能再切分的了。但是電腦的原操作,只有“與”、“或”、“異或”、“非”以及位移等操作。加法是需要用這些原操作組合起來才能實現的。

說的比較籠統。這個也不是一兩句才能說清楚的。在現在的進階語言中,加法和位元運算的操作符可以同時使用,所以我們也不需要太過深究位元運算怎麼實現加法,只要知道有位元運算這麼回事就行了。

以下是基礎的位元運算

0 & 0 = 0; 0& 1 = 0; 1 & 0 = 0; 1 & 1 = 1

0 | 0 = 0; 0 | 1= 1; 1 | 0 = 1; 1 | 1 = 1

0 ^ 0 = 0;1 ^ 0= 1;0 ^ 1 = 1; 1 ^ 1 = 0

另外,位元組的概念需要說明一下。位元組(Byte)是電腦資訊技術用於計量儲存容量和傳輸容量的一種計量單位,1個位元組等於8位二進位。Java裡的byte,就是位元組。

對於不帶正負號的整數來說,一個位元組能表示的最大的數,就是255了,也就是“11111111”。但是對於一個有符號的整數,因為需要把左邊第一位用來表示正負,所以能表示的最大的數,就是127了。也就是“0111111”。能表示的最小的數也可以如此推算。

在java裡面,一個int就是用4個位元組來表示的。因為java沒有不帶正負號的整數的類型,所以第一位一定是符號位。

如果我們把byte強制轉換成int類型,int的最低的8位與byte相同,之前的3個位元組,都用符號位來填補。也就是說,如果是一個負數byte,那麼轉化成int之後,前3個位元組都是1。

我們可以用下面這段代碼來看:

byte b1 = 10;System.out.println("b1=" + Byte.toString(b1));System.out.println("b1轉成int後的二進位:" + Integer.toBinaryString(b1));byte b2 = -10;System.out.println("b2=" + Byte.toString(b2));System.out.println("b2轉成int後的二進位:" + Integer.toBinaryString(b2));

 

結果顯示:

b1=10

b1轉成int後的二進位:1010

b2=-10

b2轉成int後的二進位:11111111111111111111111111110110

b1是正數,轉成int型後,前面補0,所以還是00001010,只是0000在轉String的時候去掉了。

b2是負數,轉成int型後,前面補1,所以就是11111111111111111111111111110110了。

細心的朋友一定發現了不對勁的地方。是的,-10的二進位,最後幾位是11110110,不是我們想象中的10001010。這裡有個概念,叫補碼。

為什麼要有這麼一個概念。還得從符號位來說。如果只是符號位來表示正負,後面的資料都一樣,那麼就會有個問題,+0和-0的事情。正數我們可以表示的從0~127,負數我們可以表示-0 ~ -127,那麼一共只能表示255個數字,因為0和-0是一個數字。為瞭解決這個問題,所以有了補碼的概念。也就是說,如果是負數,除了符號位用1表示外,剩下的位元都反一下,然後-1.

那麼,-10的二進位的推算步驟,應該是:

1,10的二進位,去掉符號位是0001010

2,減一,就是0001001

3,反過來,就是1110110

4,加上符號位,就是11110110

這種情況下,就沒有-0的概念了。10000000表示的數,應該是:

1, 去掉符號位,資料位元是0000000

2, 因為符號位是1,所以需要補碼計算

3, 反過來,就是1111111

4, 加1,就是10000000。

所以,10000000表示的十進位數是-128

這樣,一個byte可以表示 -128 ~127,正好256個數字,一個都不浪費了。

如果我們只要顯示byte的位元,那怎麼辦?那我們就先把byte轉成int,然後把前面的3個byte都去掉,只留下最後一個byte的資料就行了。代碼如下:

byte b1 = 10;System.out.println("b1=" + Byte.toString(b1));System.out.println("b1的二進位:" + Integer.toBinaryString(0xff & b1));byte b2 = -10;System.out.println("b2=" + Byte.toString(b2));System.out.println("b2的二進位:" + Integer.toBinaryString(0xff & b2));

      

主要是因為我們找不到Byte類的toBinaryString函數,所以只好借Integer的用用啦。

這裡還需要說明一下,位移操作。如果把一個byte左移一位,那麼最右邊將補一個0,最左邊的資料就丟掉了。而右移則不同,最左邊補的是符號位,也就是最高的那個位。如果是負數,右移後還是負數。

看這段代碼:

byte b1 = 10;System.out.println("位移前b1=" + Byte.toString(b1));System.out.println("位移前b1的二進位:" + Integer.toBinaryString(0xff & b1));b1 = (byte)(b1 >> 2);System.out.println("位移後b1=" + Byte.toString(b1));System.out.println("位移後b1的二進位:" + Integer.toBinaryString(0xff & b1));byte b2 = -10;System.out.println("位移前b2=" + Byte.toString(b2));System.out.println("位移前b2的二進位:" + Integer.toBinaryString(0xff & b2));b2 = (byte)(b2 >> 2);System.out.println("位移後b2=" + Byte.toString(b2));System.out.println("位移後b2的二進位:" + Integer.toBinaryString(0xff & b2));

結果就是:

位移前b1=10

位移前b1的二進位:1010

位移後b1=2

位移後b1的二進位:10

位移前b2=-10

位移前b2的二進位:11110110

位移後b2=-3

位移後b2的二進位:11111101

 

一般在什麼情況下會用到位操作呢?我的一些總結:

1,  和裝置打交道的時候

基本上和裝置的介面,都是傳遞byte數組。byte數組如果需要轉成字串,自然不需要位元運算,只需要根據碼制進行解碼即可。但是如果轉成int/long等數值,則需要用位元運算來轉換。

2,  快速運算的時候

需要×2的時候,直接左移1位,操作很快,而且省CPU。

3,  節省記憶體的時候

直接用位元運算去判斷某個位元組,比轉成String判斷更省事。

還有什麼,我倒是一下子想不起來了。後面我會展示幾段代碼以表示位元運算的好處。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.