概述
計(jì)算機(jī)存儲(chǔ)的格式是二進(jìn)制位,8個(gè)二進(jìn)制位表示一個(gè)字節(jié),在計(jì)算機(jī)中二進(jìn)制位有原碼,反碼和補(bǔ)碼的格式,下面分別介紹
原碼:最高位表示符號(hào)位,正數(shù)0,負(fù)數(shù)1;其余7位表示數(shù)值因此,一字節(jié)原碼的表示范圍-127到127
反碼:正數(shù)的反碼和原碼相同,負(fù)數(shù)的反碼為除符號(hào)位其余取反即,0變1,1變0,一字節(jié)原碼的表示范圍-127到127
補(bǔ)碼:正數(shù)的補(bǔ)碼和原碼相同,負(fù)數(shù)的補(bǔ)碼為反碼+1,一字節(jié)原碼的表示范圍-128到127
為了簡(jiǎn)化基礎(chǔ)電路設(shè)計(jì),計(jì)算機(jī)中加法就是將兩個(gè)二進(jìn)制位相加,減法就是加上一個(gè)負(fù)數(shù),對(duì)應(yīng)的符號(hào)位參與運(yùn)算,乘法是左移運(yùn)算,除法是右移運(yùn)算
使用原碼進(jìn)行計(jì)算,結(jié)果不正確,
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
使用反碼計(jì)算,在0的時(shí)候會(huì)出問題,雖然邏輯上我們理解的0和-0是一樣的,但是在反碼中的表示不一樣0的反碼是0000 0000,-0的反碼是1111 1111
1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
使用補(bǔ)碼計(jì)算,結(jié)果正確,在補(bǔ)碼中不管是0還是-0補(bǔ)碼都為0000 0000
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]補(bǔ) + [1111 1111]補(bǔ) = [0000 0000]補(bǔ)=[0000 0000]原
補(bǔ)碼的最小值為-128
(-1) + (-127) = [1000 0001]原 + [1111 1111]原 = [1111 1111]補(bǔ) + [1000 0001]補(bǔ) = [1000 0000]補(bǔ)=-128
因此計(jì)算機(jī)中存儲(chǔ)一個(gè)字節(jié)是使用補(bǔ)碼來表示,一個(gè)字節(jié)表示-128到127
編碼
計(jì)算機(jī)保存數(shù)據(jù)是通過保存二進(jìn)制數(shù)據(jù),我們使用的字符在計(jì)算機(jī)內(nèi)存儲(chǔ)的僅僅是二進(jìn)制數(shù)據(jù),那為啥會(huì)出現(xiàn)亂碼呢?這里就涉及到編碼和字符集的問題
最初計(jì)算機(jī)中只有ASCII字符集和編碼,只表示128個(gè)字符;后來計(jì)算機(jī)發(fā)展字符和編碼需要擴(kuò)充,就有了Unicode字符集和對(duì)應(yīng)的UTF-8,UTF-16等編碼。Unicode字符集表示了各個(gè)國(guó)家100多萬字符。中國(guó)也有自己的字符集和字符編碼,如GBK和GB18030
字符集相當(dāng)于字典,每一個(gè)字符都有唯一的一個(gè)id,編碼就是字符在計(jì)算機(jī)中存儲(chǔ)的形式,比如:UTF-8將字符集中的每一個(gè)字符id通過一個(gè)算法獲得了這個(gè)字符在計(jì)算機(jī)中的儲(chǔ)存格式,幾個(gè)字節(jié),每個(gè)字節(jié)的大小,因此盡管UTF-8和UTF-16都是基于Unicode字符集,但是同一個(gè)字他們的存儲(chǔ)字節(jié)數(shù),每個(gè)字節(jié)大小幾乎不盡相同
亂碼出現(xiàn)的原因就是,我這個(gè)字是基于UTF-8存儲(chǔ)的,你使用UTF-16的編碼來想翻譯我,對(duì)不起,對(duì)應(yīng)的字節(jié)數(shù)和字節(jié)大小和你想表達(dá)的字不是同一個(gè),只能給你亂碼顯示了,比如“漢”字在這兩種編碼中就有不同的顯示。
字符集和字符編碼一般都是同時(shí)制定的,編碼不止字符編碼,還有圖像聲音編碼等來保存音頻視頻
參考文章
原碼,反碼,補(bǔ)碼詳解
徹底理解字符編碼