眾所周知在計算機中所有的數據都是以二進制的方式存儲的。不管是int,String,float等等不同的數據類型,最終都會保存為01的形式。那么為什么要使用這種方式儲存數據呢?
因為計算機是一種電子設備,由復雜的電子元器件組合而成,一個電子元器件有帶電和不帶電兩種狀態,通常我們將帶電狀態表示為數值1,不帶電狀態表示為數值0,多個這樣的元器件的組合可以表示更多狀態,也就是可以表示更多的數據,如000表示0,001表示1,010表示2,011表示3,依此類推,111表示 7,一個元器件可表示一位(bit)數據,這種表示數據的方式就叫二進制。
在實際的電子設備中,我們將8個這樣的元器件形成一個單元,這樣的單元叫一個字節(byte),一個字節能表示多少個數呢?表示數值的范圍是0-255。
一個字節由8個二進位組成,其中最右邊的一位稱為“最低有效位”或“最低位”,最左邊的一位稱為“最高有效位”或“最高位”。每一個二進位的值是0或1。
二進制計數的缺點:書寫太長,容易出錯,一般計算機的數據位數都是4的整數倍,所以,在計算機里通常采用16進制計數法。用數字可以表示各種信息,計算機里只有數值,當你在內存中看到一個數值時,這個數值可能代表各種意義,生活中的數值也可以代表其他意義,如1234可以代表密碼,存款額,電報信息,根據上下線索,我們就能夠知道這數值代表的意義
但是在Java中到底是如何去保存數據的呢?下面我就以int數據類型為例說明Java的方式。
大家都知道在Java中規定1 int = 4 byte, 1 byte = 8 bit。以此推理那么1個int在計算機中就是以4 * 8 = 32位(bit)的方式存儲的。而又由于java中的int是屬于有符號類型(Java中不存在unsigned類型),所以32位的高一位是符號位,由此可以推理出int的儲存大小區間
Integer.MAX_VALUE = 2147483647(十進制) = 1111111 11111111 11111111 11111111(二進制)
Integer.MIN_VALUE = -2147483648(十進制) = 10000000 00000000 00000000 00000000(二進制)
現在我們知道了二進制的概念了,但是其實二進制我想我們想象的那么單純的表示的,他們是不同的表現方式如:原碼,反碼,補碼
將最高位作為符號位(以0代表正,1代表負),其余各位代表數值本身的絕對值(以二進制表示)。
為了簡單起見,我們用1個字節來表示一個整數。
+7的原碼為: 00000111
-7的原碼為: 10000111
一個數如果為正,則它的反碼與原碼相同;一個數如果為負,則符號位為1,其余各位是對原碼取反。
為了簡單起見,我們用1個字節來表示一個整數。
+7的反碼為: 00000111
-7的反碼為: 11111000
利用溢出,我們可以將減法變成加法。
對于十進制數,如果從9得到結果5,可以用減法:
9-4=5
因為4+6=10,我們將6作為4的補數,將上式的減法改寫為加法:
9+6=15
去掉高位1(也就是減去10),得到結果5。
對于16進制數,如果從C得到結果5,可以用減法:
C-7=5
因為7+9=16,我們將9作為7的補數,將上式的減法改寫為加法:
C+9=15
去掉高位1(也就是減去16),得到結果5。
在計算機中,如果我們用1個字節表示一個數,一個字節有8位,超過8位就進1,在內存中情況為:
1 00000000
進位1被丟棄。
一個數如果為正,則它的原碼、反碼、補碼相同;一個數如果為負,則符號位為1,其余各位是對原碼取反,然后整個數加1。
為了簡單起見,我們用1個字節來表示一個整數。
+7的補碼為: 00000111
-7的補碼為:第一步:11111000 (符號位為,其余各位取反)
第二步:11111001 (整個數加1)
+0的補碼:00000000;
-0的補碼:11111111;(第一步)
100000000;(第二步)
已知一個負數的補碼,將其轉換為十進制數,步驟:
1、先對各位取反;
2、將其轉換為十進制數;
3、加上負號,再減去1。
例如:
11111010,最高位為1,是負數,先對各位取反得00000101,轉換為十進制數得5,加上負號得-5,再減1得-6。
那么我們就知道了1與-1的二進制形式分別為0000000 00000000 00000000 00000001和11111111 11111111 11111111 11111111(Java中的數據是以補碼的形式儲存的)了。那么現在我們知道了數據是如何儲存的了。那么計算機是如何利用這些數據進行計算的呢?我們知道在計算機的CPU中只有一個加法器,所有的運算都是需要它進行的。所以在計算機里所有的加減乘除都是轉換成加法來進行運算的。那么它們是怎么轉換的呢?下面我們介紹一下二進制的運算操作
為了方便對二進制位進行操作,Java給我們提供了四個二進制位操作符:
& 按位與
| 按位或
^ 按位異或
~ 按位取反
一個房間里有兩個開關控制房間的燈的明暗。當兩個開關同時處于打開狀態時,燈才能亮。
開關1 開關2 燈的狀態
關 關 暗
開 關 暗
關 開 暗
開 開 亮
結論:按位與,只有壹(1)壹(1)為1。
一個房間里有兩個開關控制房間的燈的明暗。當任何一個開關處于打開狀態時,燈就能亮。
開關1 開關2 燈的狀態
關 關 暗
開 關 亮
關 開 亮
開 開 亮
結論:按位或,只有零(0)零(0)為0。
一個房間里有兩個開關控制房間的燈的明暗。當兩個開關處于不同狀態時,燈就能亮。
開關1 開關2 燈的狀態
關 關 暗
開 關 亮
關 開 亮
開 開 暗
結論:按位異或,只有零(0)壹(1)或壹(1)零(0)為1。
結論:對二進制數按位取反,即0變成1,1變成0。
左移:<< (相當于 乘以2)
帶符號右移:>> (相當于 除以2)
無符號右移:>>>
數 x x<<2 x>>2 x>>>2
17 00010001 00 01000100 00000100 01 00000100 01
-17 11101111 11 10111100 11111011 11 00111011 11