寫在前面:學習(xi)go語言基礎的(de)(de)時候(hou)了(le)解到int8的(de)(de)數值表(biao)(biao)示(shi)范圍為-128~127,對這(zhe)個結(jie)論性的(de)(de)結(jie)果表(biao)(biao)示(shi)了(le)解,但仔細推敲發現自己(ji)還是沒(mei)懂(dong)其所以然,查閱相關(guan)博(bo)客遂成(cheng)此篇,原理為大一學的(de)(de)數字邏(luo)輯內容。
背景知識補充:
機(ji)器數:
一個數在計算機(ji)中的二進制表示方式,叫做這個數的機(ji)器(qi)(qi)數。機(ji)器(qi)(qi)數是帶(dai)符(fu)號的,計算機(ji)用最高數位存放符(fu)號,正數為 0,負數為 1。
例如:
var number int8 = 3
對應的機器數為0000 0001 (0表示整數,1表示負數)
原碼:
原(yuan)碼就是符號位加(jia)上(shang)真值(zhi)的(de)絕對值(zhi)。比如下面這個
[+1]原(yuan) = 0000 0001
原碼(ma)是最容(rong)易理解(jie)的。因為第一位(wei)是符號(hao)位(wei),所以 8 位(wei)的二進制原碼(ma)的取值范(fan)圍是
[11111 1111,0111 1111] 即 [-127,127]
反碼:
正(zheng)數(shu)的反碼(ma)(ma)是它本身,負數(shu)的反碼(ma)(ma)是在其原(yuan)碼(ma)(ma)的基礎上,符號位不變,其余各個(ge)位取反
[+1] = [0000 0001]原 = [0000 0001]反
這樣的話,如果一個反(fan)碼(ma)表示的是(shi)負數,你無法直觀(guan)的看出它的數值,通常需(xu)要轉化(hua)成原碼(ma)再進行計算。
補碼:
整數(shu)的補碼就是(shi)它本身,負數(shu)的補碼為源碼基礎上,符號位(wei)(wei)不變,其余位(wei)(wei)取(qu)反(fan),末(mo)位(wei)(wei)+1,等價于在反(fan)碼的基礎上+1
[+1] = 原碼[0000 0001] = 反碼[0000 0001] = 補碼[0000 0001]
[-1] = 原碼[1000 0001] = 反碼[1111 1110] = 補碼[1111 1111]
原(yuan)碼->反碼->補碼的引入原(yuan)理
為簡化計(ji)算機的運算設計(ji),讓符號位參與運算,減法可視(shi)為加上一個(ge)負數(shu)
例如;
十進制(zhi)的表達式 1-1=0
1-1 = 1+(-1) = 原碼[0000 0001] + 源碼[1000 0001] = 源碼[1000 0010] = -2
結論:源碼讓符號位參與運(yun)算(suan),對于減法來(lai)說,結果是(shi)不(bu)準確的,這就是(shi)為何計算(suan)機內部不(bu)使用(yong)原(yuan)碼表示一(yi)個數
為解決原碼(ma)減法存(cun)在的(de)問(wen)題,引入(ru)反碼(ma)
1-1 = 1+(-1) = 原碼[0000 0001] + 源碼[1000 0001]=
反碼[0000 0001] + 反碼[1111 1110]= 反碼[1111 1111] = 原碼[1000 0000]=-0
結論:反碼(ma)(ma)計算(suan)減(jian)法,真(zhen)值(zhi)部分是正確的,但是存在+0和-0的問(wen)題(ti),兩(liang)個編碼(ma)(ma)[0000 0001]和[1000 0000]兩(liang)個編碼(ma)(ma)表示0
為解(jie)決補碼存在的+0 和 -0問題,引入補碼
1-1 = 1+(-1)= 原碼[0000 0001] + 源碼[1000 0001]=
補碼[0000 0001] + 補碼[1111 1111] = 補碼[0000 0000] = 原碼[0000 0000]
結論:通(tong)過引入補碼(反(fan)碼負數時符號(hao)位不變,末位加一)實現0的唯(wei)一編(bian)碼
因此(ci)可以用[1000 0000]表示-128,此(ci)時補碼的數值表示范(fan)圍為(wei)[-128,127]
注意:-128沒(mei)有原碼(ma)(ma)和反碼(ma)(ma)表示
