在昨天的文章中我們講解了什么原碼反碼補碼,以及計算機中為什么要使用補碼,在文章最后的時候我們說了一個問題,八位二進制(在Java中就是byte類型)的取值范圍是從-128到127,為什么呢?
為什么127+1的結果是-128?我們今天來詳細說明一下。
昨天雖然我們介紹了什么是補碼,但是并沒有說明補碼的由來,今天我們來講解一下。
在這里要說到一個概念 模,“?!笔侵敢粋€計量系統(tǒng)的計數(shù)范圍。如時鐘等。 時鐘的計量范圍是0~11,模=12。表示n位的二進制數(shù)計量范圍是0~2(n)-1,模=2(n),八位二進制數(shù)的模為2^8 。
任何有模的計量器,均可化減法為加法運算(這就是計算機二進制運算的原理)。假設當前時針指向10點,而準確時間是6點,調整時間可有以下兩種撥法:一種是倒撥4小時,即:10-4=6;另一種是順撥8小時:10+8=12+6=6 。在以12模的系統(tǒng)中,加8和減4效果是一樣的,因此凡是減4運算,都可以用加8來代替。對“?!倍?,8和4互為補數(shù)。實際上以12模的系統(tǒng)中,11和1,10和2,9和3,7和5,6和6都有這個特性。共同的特點是兩者相加等于模。
對于計算機,其概念和方法完全一樣。n位計算機,設n=8, 所能表示的最大數(shù)是11111111,若再加1成為100000000(9位),但因只有8位,最高位1自然丟失。又回了00000000,所以8位二進制系統(tǒng)的模為2^8。在這樣的系統(tǒng)中減法問題也可以化成加法問題,只需把減數(shù)用相應的補數(shù)表示就可以了,把補數(shù)用到計算機對數(shù)的處理上,就是補碼。
對一個正數(shù)的原碼取反加一,得到這個正數(shù)對應負數(shù)的補碼。例如~6=-7,而且加一之后會多出一個八進制補碼1000 0000,而這個補碼就對應著原碼1000 0000,數(shù)字位同時當做符號位即-128 。
所以根據(jù)以上我們可以理解為什么八位二進制數(shù)表示范圍為-128~+127。
八位二進制正數(shù)的補碼范圍是0000 0000 ~ 0111 1111 即0 ~ 127,負數(shù)的補碼范圍是正數(shù)的原碼0000 0000 ~ 0111 1111 取反加一(也可以理解為負數(shù)1000 0000 ~ 1111 1111化為反碼末尾再加一)。 所以得到 1 0000 0000 ~ 1000 0001,1000 0001作為補碼,其原碼是1111 1111(-127),依次往前推,可得到-1的補碼為1111 1111,那么補碼0000 0000的原碼是1000 0000符號位同時也可以看做數(shù)字位即表示-128,這也解釋了為什么127(0111 1111)+1(0000 0001)=-128(1000 0000)。
我不能保證每一個地方都是對的,但是可以保證每一句話,每一行代碼都是經(jīng)過推敲和斟酌的。希望每一篇文章背后都是自己追求純粹技術人生的態(tài)度。
永遠相信美好的事情即將發(fā)生。