0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
电子发烧友
开通电子发烧友VIP会员 尊享10大特权
海量资料免费下载
精品直播免费看
优质内容免费畅学
课程9折专享价
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

數(shù)據(jù)表示與編碼的奧秘:為什么8位數(shù)據(jù)范圍是-128到127?

嵌入式情報(bào)局 ? 來源:invalid s ? 2024-04-17 09:44 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

很表面很淺薄的問題。

簡單說愛怎么規(guī)定就怎么規(guī)定,甚至-1到254都行。無非是顯示時(shí)通過編碼表做個(gè)轉(zhuǎn)換的問題而已。

不過,當(dāng)初選擇“補(bǔ)碼”這種編碼形式,卻并不像表面看起來那么淺薄。背后的道道可多著呢。

首先,8位二進(jìn)制一共可以提供256個(gè)“碼點(diǎn)”;那么我們就總可以用這些“碼點(diǎn)”來編碼256種符號(hào)。

這種編碼方案有很多。最著名的大概就是ASCII碼方案了,這個(gè)方案規(guī)定了英文字符(區(qū)分大小寫)、0~9這10個(gè)數(shù)字、標(biāo)點(diǎn)符號(hào)以及一些控制字符如何編碼:

d53385be-fc02-11ee-a297-92fbcf53809c.jpg

但ASCII碼用來編碼字符效果不錯(cuò);拿來存儲(chǔ)數(shù)字卻極為浪費(fèi)。比如它需要三個(gè)字節(jié)才能表示123。

為了編碼數(shù)字,我們需要一個(gè)更有效的方案。

一種很自然的想法是,我們就直接把二進(jìn)制對(duì)應(yīng)的數(shù)字值拿來用,這就是最好的編碼方案!

于是,8個(gè)二進(jìn)制位就可以表示0~255之間的所有數(shù)字——用ASCII碼三個(gè)字節(jié)才能表示的123,直接用二進(jìn)制編碼就是01111011,一個(gè)字節(jié)足夠了。

這個(gè)方案只能表示正數(shù);遇到負(fù)數(shù)怎么辦呢?

簡單,第一個(gè)二進(jìn)制位拿出來當(dāng)符號(hào)位,剩下七位仍然當(dāng)數(shù)字用,就能表示±127之間的任何數(shù)字了。

這個(gè)方案就叫“原碼”;其中不帶符號(hào)位的就是無符號(hào)數(shù)(unsigned)。

原碼是一種很初級(jí)的編碼方案,它僅僅解決了編碼問題——從此數(shù)字有辦法二進(jìn)制表示了。

但我們?cè)谟?jì)算機(jī)內(nèi)部表示數(shù)字是用來計(jì)算的;那么想用原碼計(jì)算的話,那可就麻煩了……

我們知道,最初CPU的內(nèi)部最重要的核心器件叫ALU(Arithmetic and Logic Unit算術(shù)邏輯單元),其中的A就是數(shù)學(xué)。

ALU的核心是加法器,這是個(gè)隨參與計(jì)算的數(shù)值的二進(jìn)制位數(shù)指數(shù)增長的數(shù)字電路。較早期的CPU里面絕大多數(shù)的邏輯門都被拿來做這個(gè)加法器了。

加法器顧名思義只能拿來做加法。

但是沒關(guān)系,如果你調(diào)過機(jī)械表,就知道從8點(diǎn)調(diào)到1點(diǎn)的方式有兩種:一種是往后撥7個(gè)小時(shí),一種是往前撥5個(gè)小時(shí)。

換句話說,在時(shí)鐘鐘面上,8-7和8+(12-7)效果相同,最終得到的都是1.

類似的,1個(gè)字節(jié)的加減法,如果計(jì)算結(jié)果超過255就會(huì)造成溢出,溢出的高位二進(jìn)制數(shù)據(jù)無處存放自動(dòng)丟棄,計(jì)算結(jié)果就出錯(cuò)了——但反過來想,這不恰恰就是一個(gè)邏輯鐘面嗎?

顯然,我們也可以利用這個(gè)性質(zhì)做減法:減32完全可以當(dāng)成加(256-32)來算嘛;而由于二進(jìn)制的特點(diǎn),256-32恰好又等于32這個(gè)數(shù)值取反。

類似的,有符號(hào)數(shù)其實(shí)是一個(gè)符號(hào)位和7個(gè)二進(jìn)制位,7個(gè)二進(jìn)制位能表示的最大數(shù)是127;因此減32就可以用加(128-32)代替(和表盤上的12點(diǎn)/0點(diǎn)一樣)。

于是,減法器就可以不做,一個(gè)加法器就足夠用了——省了好大一坨門電路,CPU的制造成本一下子就去了一大塊。

既然最終減法一定要這樣做……那么從一開始就不應(yīng)該用原碼表示負(fù)數(shù),對(duì)吧。

不然每次計(jì)算都還得用一條指令判斷判斷符號(hào)位,然后該取反取反……這速度可就慢下去了。

如果從一開始,負(fù)數(shù)就取反表示,那么負(fù)數(shù)加法完全無需判斷,拎起來就加——圓滿。

這個(gè)編碼方案就是所謂的反碼。

反碼是一個(gè)充滿了工程師的惡臭味的優(yōu)秀方案。

說它優(yōu)秀,是因?yàn)樗拇_解決問題;說它惡臭,是因?yàn)樗闷饋韺?shí)在麻煩,需要很多“微妙”的調(diào)整才能得到正確結(jié)果。

比如,它的符號(hào)位相加后,如果產(chǎn)生了進(jìn)位,就要把進(jìn)位送回去加到最低位上——你得搞一大張真值表才能確定這個(gè)做法的正確性。

嗯……這就是最容易產(chǎn)生沒人看得懂但絕對(duì)不能動(dòng)不然就會(huì)出錯(cuò)的神奇代碼的重災(zāi)區(qū)——反正它就是能工作;剛開始我還知道為什么得這樣做,一段時(shí)間后就只有上帝知道了。

反碼行為奇特的根本原因在于,它有兩個(gè)零:+0和-0,分別對(duì)應(yīng)于00000000和10000000——還記得嗎?我們規(guī)定第一位是符號(hào)位。因此最前面的0/1是±號(hào),并不是數(shù)值。

但+0和-0都是0.它們是同一個(gè)數(shù)據(jù),卻得到了兩個(gè)碼點(diǎn)。

打個(gè)比方的話,這就好像夜里12點(diǎn)就是0點(diǎn)一樣;結(jié)果我們的鐘匠師傅沒想明白,偏偏要在鐘面上、12點(diǎn)和1點(diǎn)之間添加一個(gè)零點(diǎn)——然而邏輯上我們?nèi)匀恍枰?2小時(shí)是一圈。

現(xiàn)在,你還想好好調(diào)表嗎?算的準(zhǔn)準(zhǔn)的,8點(diǎn)前擰5個(gè)小時(shí)就是1點(diǎn)了;結(jié)果擰完一看,0點(diǎn)?

徹底亂套了,對(duì)吧。

而反碼的計(jì)算規(guī)則呢,無異于規(guī)定了過12點(diǎn)的方向——正著過正常去1點(diǎn),反著過會(huì)先停在-0點(diǎn)上,所以必須推一把。

注意這個(gè)調(diào)整是計(jì)算過程的一部分,每次計(jì)算都必須即時(shí)調(diào)整。這是一個(gè)額外的負(fù)擔(dān)——和顯示時(shí)查表轉(zhuǎn)換到光學(xué)點(diǎn)陣/向量是不想干的兩個(gè)過程。

或者說,數(shù)據(jù)的內(nèi)部表示和外部顯示之間的轉(zhuǎn)換是另外一個(gè)必不可少的流程。這里只要不是太過復(fù)雜就不能算額外負(fù)擔(dān);而原碼/反碼這兩個(gè)編碼方案已經(jīng)影響了計(jì)算過程,造成了額外的性能消耗。

一言以蔽之:能解決問題,但是太難看、太復(fù)雜。

一個(gè)更好的方案叫補(bǔ)碼。

但是在介紹補(bǔ)碼之前,我先來講一個(gè)數(shù)學(xué)概念—群。

群大概來源于“算術(shù)運(yùn)算以及適用算法運(yùn)算的集合”的抽象,但又超脫于簡單的四則運(yùn)算,是一切計(jì)算/變換類似行為的總綱。

在群的觀念里,加減乘除都是一種“二元運(yùn)算”;二元運(yùn)算是一個(gè)集合G中任意兩個(gè)元素向群中另一個(gè)元素的映射。比如1+1就映射到了2。

注意群有“封閉性”,意思是群中任意兩個(gè)元素經(jīng)過二元運(yùn)算后,映射的那個(gè)元素都還要在群中。因此(自然數(shù),加減法)就不是一個(gè)群,因?yàn)闇p法會(huì)映射到負(fù)數(shù)。

此外,二元運(yùn)算需要滿足結(jié)合律,要有單位元(任何元素與之執(zhí)行二元運(yùn)算后都會(huì)映射到該元素自身),等等。

更復(fù)雜的東西我也還看不懂(對(duì)不起,俺數(shù)學(xué)水平太弱雞了);但了解這么多其實(shí)也已經(jīng)夠了:反碼存在兩個(gè)0,意味著對(duì)于加法運(yùn)算來說,它存在兩個(gè)不同的單位元;而根據(jù)群的定義,群里面有且只有一個(gè)單位元。

因此,在反碼這個(gè)基礎(chǔ)上無法定義一個(gè)群——用人話說就是,你不可能期望找到一種不需要判斷的算法,從而基于反碼模擬加減法運(yùn)算。

沒錯(cuò),反碼有兩個(gè)零這事并不像外行想象的那樣無關(guān)痛癢——它并不僅僅是浪費(fèi)了一個(gè)碼點(diǎn)的問題,而是破壞了相關(guān)結(jié)構(gòu)的性質(zhì)的問題。

如何解決這個(gè)問題呢?

不妨返璞歸真,看看這個(gè)問題的本質(zhì)。

很簡單,和上面等待寫入時(shí)間信息的無字鐘面一樣:這里有256個(gè)不同的二進(jìn)制編碼,我們需要給它們分別指定一個(gè)意義。

我們希望它們是連續(xù)的編碼,且基于二進(jìn)制的排序不能打亂——這樣我們才能使得基于這些碼點(diǎn)的、拋棄溢出位的加減法運(yùn)算構(gòu)成一個(gè)群。

只有它們是一個(gè)群,我們才能簡單明了的在加法器上支持加減法運(yùn)算——而不是先算一個(gè)瑕疵值然后想辦法彌補(bǔ)、把硬件/軟件變得復(fù)雜。

打個(gè)比方的話,就是把這些二進(jìn)制編碼按順序排于鐘面,我們要在上面填上帶±號(hào)的數(shù)字。

原碼的問題在于,它的編碼排列“不按固定順序”,使得因此必須把負(fù)數(shù)先“顛倒”一下(實(shí)際上取反)才能用;而反碼頭疼醫(yī)頭腳疼醫(yī)腳,大致保證了編碼順序,卻沒能消除額外的無效碼點(diǎn),造成在±0這個(gè)位置兩個(gè)碼點(diǎn)對(duì)應(yīng)一個(gè)編碼。

這兩個(gè)編碼都沒法自然構(gòu)造出加法群。

借用@任衛(wèi)同學(xué)的這張圖:

d5543caa-fc02-11ee-a297-92fbcf53809c.jpg

可以很清晰的看出補(bǔ)碼編碼的連續(xù)性。

(相比之下,原碼是0 1 2 3……127 -0 -1 -2……-127,順序上一會(huì)兒從小到大一會(huì)兒從大到??;補(bǔ)碼按照一定的順序編碼但是多了個(gè)-0;

只有補(bǔ)碼,嚴(yán)格按照統(tǒng)一的順序連續(xù)排列數(shù)字)。

既然連續(xù),那么通過加一個(gè)值(可能為負(fù))調(diào)整對(duì)稱中心(比如0的位置是00000000還是11111111)、然后再引入模運(yùn)算剔除高位溢出,這個(gè)群就建立起來了。

換句話說,隨便你如何編碼,只要?jiǎng)e改變底層的二進(jìn)制順序、不要有跳躍/重復(fù)碼點(diǎn),那么這個(gè)計(jì)算就仍然是一個(gè)群。

這個(gè)計(jì)算過程和最終的顯示是完全脫鉤的,你不需要在計(jì)算時(shí)做任何調(diào)整——溢出就隨它溢出,反正(在模運(yùn)算的層面上)算出來的值總是對(duì)的。這是群的性質(zhì)所保證的。

(注意是“模運(yùn)算的層面上”,換句話說算出來的實(shí)際意義是什么還是得你自己解釋;尤其是產(chǎn)生溢出之后。)

比如,哪怕你把它的編碼范圍改成[-129, 126]或者[-1, 254],這也僅僅是一個(gè)加/減一個(gè)整數(shù)的映射操作而已;核心計(jì)算法則仍然會(huì)滿足你的需求)。

甚至,你規(guī)定0代表1、1代表0,最終也不過是顯示時(shí)換一個(gè)不同的譯碼表而已,并不改變問題性質(zhì)。

這個(gè)性質(zhì)是普適的。

7位、8位或者32位、128位二進(jìn)制全都適用。

一旦明白了這個(gè)……再寫環(huán)形緩沖時(shí),你還要費(fèi)勁巴拉的檢查什么時(shí)候需要繞回嗎?求個(gè)余(或許還需要再視情況不同增減一個(gè)常數(shù)),完事。

你看,數(shù)學(xué)這種東西厲害吧?

哪怕群論門檻都摸不到的這么一點(diǎn)點(diǎn)皮毛知識(shí),帶來的就是眼界水平的差異。

一旦了解了這點(diǎn)皮毛,關(guān)于補(bǔ)碼的種種清規(guī)戒律神奇規(guī)則,也就平常。

但沒有這個(gè)眼界,就容易像反碼那樣動(dòng)輒得咎;反之,隨你怎么玩都不會(huì)出界。

沒錯(cuò)。別看這東西簡單;

但想要做第一個(gè)提出的人,你還是需要強(qiáng)悍的洞察力的。

站在群論的肩膀上、反向碾壓這個(gè)問題,這是伽羅瓦之后的現(xiàn)代人特有的福利。

審核編輯:黃飛

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • cpu
    cpu
    +關(guān)注

    關(guān)注

    68

    文章

    11076

    瀏覽量

    216999
  • 邏輯門
    +關(guān)注

    關(guān)注

    1

    文章

    147

    瀏覽量

    25036
  • 加法器
    +關(guān)注

    關(guān)注

    6

    文章

    183

    瀏覽量

    30756
  • ASCII
    +關(guān)注

    關(guān)注

    5

    文章

    172

    瀏覽量

    35857
  • 減法器
    +關(guān)注

    關(guān)注

    1

    文章

    26

    瀏覽量

    17129

原文標(biāo)題:為什么8位數(shù)據(jù)范圍是-128到127,而不是-127到128?

文章出處:【微信號(hào):嵌入式情報(bào)局,微信公眾號(hào):嵌入式情報(bào)局】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 0人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    請(qǐng)問HT1621驅(qū)動(dòng)芯片內(nèi)部RAM中的4位數(shù)據(jù)表示什么?

    HT1621驅(qū)動(dòng)芯片內(nèi)部RAM中的4位數(shù)據(jù)表示什么?就我理解的話每個(gè)seg信號(hào)是確定哪一個(gè)段亮,而對(duì)應(yīng)地址的數(shù)據(jù)究竟是控制什么的?
    發(fā)表于 07-04 17:35

    C語言單片機(jī)編程為什么總是用無符號(hào)的數(shù)據(jù)類型來定義

    注意:答案和題目均轉(zhuǎn)自百度知道char型可以表示數(shù)的范圍是-128127,所占位數(shù)
    發(fā)表于 07-01 08:07

    數(shù)據(jù)表示—常用的信息編碼

    數(shù)據(jù)表示—常用的信息編碼 一.邏輯數(shù)據(jù)表示 邏輯數(shù)據(jù)是用來表示二值邏輯中的“是”與“否”或
    發(fā)表于 04-15 14:36 ?2308次閱讀

    為什么在計(jì)算機(jī)里Byte是從-128127?

    計(jì)算機(jī)是一個(gè)很神奇的東西,僅靠 0 和 1 就能運(yùn)算、存儲(chǔ)等操作。那么,為什么Byte是從是從-128127? 今天就給大家講講計(jì)算機(jī)二進(jìn)制的一些內(nèi)容。 1 計(jì)算機(jī)表示
    的頭像 發(fā)表于 04-15 11:43 ?3540次閱讀

    AD1933:帶PLL和差分輸出的8通道DAC,192 kHz,24位數(shù)據(jù)表

    AD1933:帶PLL和差分輸出的8通道DAC,192 kHz,24位數(shù)據(jù)表
    發(fā)表于 04-15 16:36 ?8次下載
    AD1933:帶PLL和差分輸出的<b class='flag-5'>8</b>通道DAC,192 kHz,24<b class='flag-5'>位數(shù)據(jù)表</b>

    AD1934:帶PLL和單端輸出的8通道DAC,192 kHz,24位數(shù)據(jù)表

    AD1934:帶PLL和單端輸出的8通道DAC,192 kHz,24位數(shù)據(jù)表
    發(fā)表于 04-15 19:00 ?5次下載
    AD1934:帶PLL和單端輸出的<b class='flag-5'>8</b>通道DAC,192 kHz,24<b class='flag-5'>位數(shù)據(jù)表</b>

    ADV7196A:多格式逐行掃描/HDTV編碼器,3個(gè)11DAC,10位數(shù)據(jù)輸入和宏視數(shù)據(jù)表

    ADV7196A:多格式逐行掃描/HDTV編碼器,3個(gè)11DAC,10位數(shù)據(jù)輸入和宏視數(shù)據(jù)表
    發(fā)表于 04-23 17:22 ?2次下載
    ADV7196A:多格式逐行掃描/HDTV<b class='flag-5'>編碼</b>器,3個(gè)11<b class='flag-5'>位</b>DAC,10<b class='flag-5'>位數(shù)據(jù)</b>輸入和宏視<b class='flag-5'>數(shù)據(jù)表</b>

    AD7314:8引線μSOIC數(shù)據(jù)表中的低壓10位數(shù)字溫度傳感器

    AD7314:8引線μSOIC數(shù)據(jù)表中的低壓10位數(shù)字溫度傳感器
    發(fā)表于 05-07 21:26 ?3次下載
    AD7314:<b class='flag-5'>8</b>引線μSOIC<b class='flag-5'>數(shù)據(jù)表</b>中的低壓10<b class='flag-5'>位數(shù)</b>字溫度傳感器

    AD7376:+30 V/±15 V操作128位數(shù)字電位器數(shù)據(jù)表

    AD7376:+30 V/±15 V操作128位數(shù)字電位器數(shù)據(jù)表
    發(fā)表于 05-16 17:51 ?2次下載
    AD7376:+30 V/±15 V操作<b class='flag-5'>128</b><b class='flag-5'>位數(shù)</b>字電位器<b class='flag-5'>數(shù)據(jù)表</b>

    LTC1090:單片機(jī)10位數(shù)據(jù)采集系統(tǒng)數(shù)據(jù)表

    LTC1090:單片機(jī)10位數(shù)據(jù)采集系統(tǒng)數(shù)據(jù)表
    發(fā)表于 05-22 09:50 ?7次下載
    LTC1090:單片機(jī)10<b class='flag-5'>位數(shù)據(jù)</b>采集系統(tǒng)<b class='flag-5'>數(shù)據(jù)表</b>

    ADV7195:帶三個(gè)11DAC和10位數(shù)據(jù)輸入數(shù)據(jù)表的多格式逐行掃描/HDTV編碼

    ADV7195:帶三個(gè)11DAC和10位數(shù)據(jù)輸入數(shù)據(jù)表的多格式逐行掃描/HDTV編碼
    發(fā)表于 05-24 19:22 ?1次下載
    ADV7195:帶三個(gè)11<b class='flag-5'>位</b>DAC和10<b class='flag-5'>位數(shù)據(jù)</b>輸入<b class='flag-5'>數(shù)據(jù)表</b>的多格式逐行掃描/HDTV<b class='flag-5'>編碼</b>器

    603-24-127 數(shù)據(jù)表

    603-24-127 數(shù)據(jù)表
    發(fā)表于 05-15 18:35 ?0次下載
    603-24-<b class='flag-5'>127</b> <b class='flag-5'>數(shù)據(jù)表</b>

    603-24-127 數(shù)據(jù)表

    603-24-127 數(shù)據(jù)表
    發(fā)表于 07-11 19:45 ?0次下載
    603-24-<b class='flag-5'>127</b> <b class='flag-5'>數(shù)據(jù)表</b>

    TLV571 8位數(shù)據(jù)采集系統(tǒng)數(shù)據(jù)表

    電子發(fā)燒友網(wǎng)站提供《TLV571 8位數(shù)據(jù)采集系統(tǒng)數(shù)據(jù)表.pdf》資料免費(fèi)下載
    發(fā)表于 07-29 11:13 ?0次下載
    TLV571 <b class='flag-5'>8</b><b class='flag-5'>位數(shù)據(jù)</b>采集系統(tǒng)<b class='flag-5'>數(shù)據(jù)表</b>

    labview數(shù)據(jù)類型的取值范圍是多少

    ) :取值范圍是-128127。這是因?yàn)樗褂昧?b class='flag-5'>8二進(jìn)制數(shù)
    的頭像 發(fā)表于 09-04 17:33 ?2611次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會(huì)員交流學(xué)習(xí)
    • 獲取您個(gè)性化的科技前沿技術(shù)信息
    • 參加活動(dòng)獲取豐厚的禮品