Java中負數以及類型轉換問題,java負數類型轉換
學習過java的都知道,在java中,不是直觀的表示負數,而是採用補碼的形式表示負數。
這是為了硬體操作的方便,把減法也轉換成加法來運算。
那補碼是怎樣表示的呢?為了得到補碼,我們引入了反碼。
對於正數來講,它的反碼補碼都為本身,如果不明白為什麼,我們可以這樣理解:引入反碼補碼的原因就是為瞭解決減法的問題,換句話數就是解決java中負數的問題,正數不存在這些問題,所以它的反碼補碼就是它本身。在有符號的基礎資料型別 (Elementary Data Type)中,最高位0表示正數,最高位1表示負數。 對於負數來講,它的反碼就是除去符號位取反,然後加1就得到了它的補碼。
這裡舉個簡單的例子,一個byte型資料,它在電腦中佔8位,-7可以表示為10000111,最高位的1代表負號,它的反碼是除去符號位各位取反為11111000,然後加1得到補碼11111001。
8的二進位表示為00001000,現在我們運算8 - 7,在電腦並不是用8減去7,而是用8 + (-7),也就是用00001000加上-7的補碼11111001,兩個有符號數相加,如果符號位相加有近位就刪去符號位的進位,得到00000001,也就是1.
java中我們經常也會遇到不同資料類型的轉換,這是最容易出錯的地方。
首先我們瞭解一下什麼是符號擴充,對於正數來講,在前面補0; 負數時在前面補1。比如8位的位元10000111擴充為16位,我們在前面加上8個1,1111111110000111;如果是正數,則在前面補0。這樣進行擴充後,符號和數值的大小都不變。
接下來我們我們看一下不同類型之間是怎樣轉換的,首先我們要知道這些基本類型各自占幾位。 有符號型: byte = 8 int = 32 short = 16 long = 64 float = 32 double = 64 *boolean 只佔一位,用0和1代表false和true。
無符號型: char = 16
1. byte型轉為char型 因為byte是有符號類型,再轉成char型時需要進行符號位擴充,如果是正數就在前面不上8個0, 如果是負數就在前面補上8個1。例如11111111(0xff)左邊連續補上8個1結果是0xffff。因為char是無符號類型,所以0xffff表示的十進位數是65535。
2. char型轉為int型 因為char是無符號類型,轉換成int型時進行在前面補上16個0,用十進位表示結果為結果0x0000ffff,對應的十進位數是65535。
3. int型轉為byte型 因為int是32位,而byte類型值只佔8位,直接截取最後8位。例如-1的補碼為0xffffffff,轉換為byte型後為0xff,值為-1。
總結:如果最初的數實值型別是有符號的,那麼就執行符號擴充;如果是char類型,那麼不管它要被轉換成什麼類型,都執行零擴充。還有另外一條規則也需要記住,如果目標類型的長度小於源類型的長度,則直接截取目標類型的長度。例如將int型轉換成byte型,直接截取int型的右邊8位。