最近在學(xué)Swift, 在學(xué)到高級(jí)運(yùn)算符的時(shí)候, 用到了位運(yùn)算, 然后發(fā)現(xiàn)自己把計(jì)算機(jī)基礎(chǔ)的進(jìn)制忘的差不多了. 在這里記錄學(xué)習(xí)一下
計(jì)算機(jī)里面所有數(shù)都以補(bǔ)碼形式保存,加減運(yùn)算都是補(bǔ)碼之間的加法運(yùn)算矫夷。
原碼
原碼就是加了符號(hào)位的機(jī)器數(shù), 比如一個(gè)八位的二進(jìn)制數(shù), 第一位是符號(hào)位, 后面七位是數(shù)字位.
符號(hào)位是0, 表示正數(shù), 1表示負(fù)數(shù). 但是只能表示255個(gè)狀態(tài),即-127到+127之間的數(shù)字, +0 (00000000)和 -0(10000000)都表示0, 少了一個(gè)狀態(tài), 由后面的補(bǔ)碼解決.
反碼
所謂反碼捉蚤,英語里又叫ones' complement(對(duì)1求補(bǔ))州袒,這里的1麦轰,本質(zhì)上是一個(gè)有限位計(jì)數(shù)系統(tǒng)里所能表示出的最大值怜庸,在8位二進(jìn)制里就是11111111河狐,在1位十進(jìn)制里就是9米绕,在3位十六進(jìn)制里就是FFF(再大就要進(jìn)位了)。求反又被稱為對(duì)一求補(bǔ)馋艺,用最大數(shù)減去一個(gè)數(shù)就能得到它的反栅干,很容易看出在二進(jìn)制里11111111減去任何數(shù)結(jié)果都是把這個(gè)數(shù)按位取反,0變1捐祠,1變零非驮,所以才稱之為反碼。用原碼求反碼的方法是雏赦,正數(shù)不變劫笙,負(fù)數(shù)保留符號(hào)位1不變,剩下位按位取反星岗。
求1的反碼
1111 1111
1
= 1111 1110
或者 -1原碼就是 1000 0001 符號(hào)位不變, 其他為按位取反
補(bǔ)碼
所謂補(bǔ)碼填大,英語里又叫two's complement(對(duì)2求補(bǔ)),這個(gè)2指的是計(jì)數(shù)系統(tǒng)的容量(模)俏橘,就是計(jì)數(shù)系統(tǒng)所能表示的狀態(tài)數(shù)允华。對(duì)1位二進(jìn)制數(shù)來說只有0和1兩種狀態(tài),所以模是10也就是十進(jìn)制的2,對(duì)7位二進(jìn)制數(shù)來說就是10000000靴寂,這個(gè)模是不可能取到的磷蜀,因?yàn)槲粩?shù)多一位。用模減去一個(gè)數(shù)(無符號(hào)部分)就能得到這個(gè)數(shù)的補(bǔ)百炬,比如10000000-1010010=0101110褐隆,事實(shí)上因?yàn)?0000000=1111111+1,稍加改變就成了(1111111-1010010)+1剖踊,所以又可以表述為先求反再加1庶弃。總結(jié)求補(bǔ)碼的方法就是正數(shù)依舊不變德澈,負(fù)數(shù)保留符號(hào)位不變歇攻,先求反碼再加上1。
補(bǔ)數(shù) 和 補(bǔ)碼的定義式 里面梆造,根本就沒有什么符號(hào)位缴守。這最高位的1、0是自然出現(xiàn)的镇辉,并不是由人來規(guī)定的斧散。的確,符號(hào)位在補(bǔ)碼運(yùn)算里面是“奶”,本身并不帶符號(hào)的意義栈暇。因?yàn)橛?jì)算機(jī)將加法轉(zhuǎn)換成加上一個(gè)“負(fù)數(shù)”麻裁,而負(fù)數(shù)又以補(bǔ)碼的形式表現(xiàn)。補(bǔ)碼比源碼多一位源祈,從這多出來的一位可以推斷出原來數(shù)字的正負(fù)號(hào)煎源,所以成為了符號(hào)位。也可以這樣認(rèn)為香缺,留出一位(不全部占滿)的原因是要用“氖窒”來表示正負(fù)數(shù)。
模
這個(gè)對(duì)于理解補(bǔ)碼很關(guān)鍵. 在我的理解模類似各種不同的進(jìn)制, 比如我們常見的星期, 7進(jìn)制, 時(shí)鐘, 12進(jìn)制, 24進(jìn)制等.
-128的補(bǔ)碼
-128的模是10000 0000, 絕對(duì)值是128, 二級(jí)制是1000 0000
10000 0000
- 1000 0000
= 1000 0000
補(bǔ)碼轉(zhuǎn)原碼
補(bǔ)碼的第一位是0則是正數(shù), 是1則是負(fù)數(shù), 取反后加1就是原碼