我們看下面這段代碼
輸出的結果的是128,這個沒什么疑問
但是當我們不改變數值僅僅加了一個強制轉換后
這時我們會發現結果會變成負的128.這時候我們就要懷疑了,為什么會出現這樣的結果呢?
對於這個問題,我們就要深入到計算機的組成原理中去了。計算機存儲數據是用二進制的0和1代碼存儲的,也就是硬件層面的高低電平。但是在用戶編程層面,我們仍然是用着我們習慣的十進制或者其它方便計算的進制的進行編程的。在java的基本數據類型中,byte類型的大小是一個字節即8個比特,放到計算中存儲就是8個存儲空間,每個存儲空間可以放0或者1;同理int類型是四個字節大小,即32個bit大小。計算機為了方便表示數的正負時將數的二進制碼的最高位作為數的正負表示,通常是0表示正數,1表示負數。這樣在真正在表示數時候只有比原類型總共空間大小少一位的位數來表示,例如int型的數據空間大小是32,但只有31個空間用來表示數值部分的,最高位用來表示正負。同時又為了方便進行數值的加減操作,引入了補碼這個概念,補碼是在源碼的基礎上除符號位外進行的各位取反后再加1獲得的,但是正數的補碼是不變的,還是源碼本身。例如10的源碼(01010)B,補碼也是(01010)B,-10的源碼是(11010)B,補碼則是(10110)B,計算機存儲時,存的就是-10的補碼(10110)B,而不是(11010)B.
弄清楚這個后,我們再來看int型的128在計算機中存儲二進制碼是0000 0000 0000 0000 0000 000 1000 0000 占據空間為32,最高位0表示這個數是正數,但是當我們強制轉換這個int型的數據為byte型,由於byte型只占據一個字節8個比特的空間,就只會截取int型數據的低八位空間中的數據作為新的數據,高位舍棄,也就是1000 0000,此時這里面的1表示這個新的數據是個負數,而且是補碼形式,要算出原數值就要先-1得0111 1111再各位取反是1000 0000,這個值就是真實值的絕對值128,加上符號后就是-128. 因此在進行強制轉換時我要要注意數據的溢出問題。