1. 程式人生 > >關於Java中byte型別為什麼是-128~127的論證

關於Java中byte型別為什麼是-128~127的論證

開發十年,就只剩下這套架構體系了! >>>   

原始碼、反碼和補碼之間的關係

  • 機器數:一個數在計算機中的二進位制表示形式, 叫做這個數的機器數。機器數是帶符號的,在計算機用一個數的最高位存放符號。正數為0, 負數為1。
比如:十進位制中的數 +3 ,計算機字長為8位,轉換成二進位制就是00000011。如果是 -3 ,就是 10000011 。那麼,這裡的 00000011 和 10000011 就是機器數。
  • 真值:因為第一位是符號位,所以機器數的形式值就不等於真正的數值。為區別起見,將帶符號位的機器數對應的真正數值稱為機器數的真值。
例如:上面的有符號數 10000011,其最高位1代表負,其真正數值是 -3 而不是形式值131(10000011轉換成十進位制等於131)
例:0000 0001的真值 = +000 0001 = +1,1000 0001的真值 = –000 0001 = –1
  • 原碼:原碼就是符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值。
比如:如果是8位二進位制:[+1]原 = 0000 0001 [-1]原 = 1000 0001 第一位是符號位. 
因為第一位是符號位, 所以8位二進位制數的取值範圍就是:[1111 1111 , 0111 1111]即[-127 , 127]。原碼是人腦最容易理解和計算的表示方式.
  • 反碼:反碼的表示方法是:正數的反碼是其本身,負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反。
[+1] = [00000001]原 = [00000001]反 
[-1] = [10000001]原 = [11111110]反
可見如果一個反碼錶示的是負數, 人腦無法直觀的看出來它的數值. 通常要將其轉換成原碼再計算.
  • 補碼:正數的補碼就是其本身.負數的補碼是在其原碼的基礎上, 符號位不變, 其餘各位取反, 最後+1. (即在反碼的基礎上+1)

Java中byte型別為什麼是-128~127

  • 現在我們知道了計算機中有3種編碼方式表現一個數
對於正數[+1] = [00000001]原 = [00000001]反 = [00000001]補
對於負數[-1] = [10000001]原 = [11111110]反 = [11111111]補
  • 由此可見,原碼、反碼和補碼完全不同,既然反碼和補碼都難以被人們接受,那為什麼還要有呢?
  • 為了讓計算機的運算更加方便,人們便設計出讓它只做加法,不做減法,並且符號位也參與加法。
    • 如:1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
  • 如果只讓原碼參與運算,對於負數,運算的結果顯然不對。為了解決原碼做減法的問題, 出現反碼。
    • 1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
  • 發現用反碼計算減法, 結果的真值部分是正確的. 而唯一的問題其實就出現在”0”這個特殊的數值上. 雖然人們理解上+0和-0是一樣的, 但是0帶符號是沒有任何意義的. 而且會有[0000 0000]原和[1000 0000]原兩個編碼表示0.
  • 於是補碼的出現, 解決了0的符號以及兩個編碼的問題
    • 1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 =[0000 0001]反 + [1111 1110]反= [0000 0001]補 + [1111 1111]補 = [0000 0000]補=[0000 0000]原
  • 這樣0用[0000 0000]表示, 而以前出現問題的-0則不存在了.而且可以用[1000 0000]表示-128
    • (-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]補 + [1000 0001]補 = [1000 0000]補
  • -1-127的結果應該是-128, 在用補碼運算的結果中, [1000 0000]補 就是-128. 但是注意因為實際上是使用以前的-0的補碼來表示-128, 所以-128並沒有原碼和反碼錶示.(對-128的補碼錶示[1000 0000]補算出來的原碼是[0000 0000]原, 這是不正確的),使用補碼, 不僅僅修復了0的符號以及存在兩個編碼的問題, 而且還能夠多表示一個最低數. 這就是為什麼8位二進位制, 使用原碼或反碼錶示的範圍為[-127, +127], 而使用補碼錶示的範圍為[-128, 127]。
  • 因為機器使用補碼, 所以對於程式設計中常用到的32位int型別, 可以表示範圍是: [-231, 231-1] 因為第一位表示的是符號位.而使用補碼錶示時又可以多儲存一個最小值。其他型別多出一位數,也都是一