要想知道計算機是如何進行運算的,就要先知道就計算機是如何進行存儲數據的;編輯器
接下來,咱們談一談計算機是怎樣存儲數據的;學習
數據存儲:編碼
咱們知道生活中數據是以不一樣的形式出現的,如數字,文本等;如下將介紹數據的存儲形式有數字,文本,音頻,圖像以及視頻,咱們將重點討論數字的存儲;spa
在計算機行業中,咱們使用多媒體這一術語來定義數字,文本,圖像,音頻和視頻的信息;設計
全部計算機外部的數據類型的數據都是採用統一的數據表示法轉換後存入計算機的,咱們稱這種通用的格式爲 位模式;3d
1:位(bit)是存儲在計算機的最小單位,它一般有兩種狀態,0和1。位表明設備的某一種狀態,這些設備只能處於這兩種狀態之一;code
例如:開關要麼是合上的,要麼斷開,那麼用1表示合上的狀態,0就是斷開狀態;視頻
在今天,計算機使用各類各樣的雙態設備來存儲數據的;blog
2:位模式是用來表示數據的不一樣種類型,它是一個序列,例如:1 0 0 0 1 0 1 0 1 1 1 1 1 1 0 1 展現了由16位組成的位模式,這就意味着要存儲一個由16個位組成的位模式,就須要16個開關。一般長度爲8的位模式成爲一個字節;內存
不一樣類型的數據能夠用一樣的位模式存儲在計算機當中,這須要一箇中間的介質(程序);
例如:須要存儲數字65 ,即 數字65→程序(數學公式)→01000001(存儲器);
鍵盤輸入字符‘A’→程序(文本編輯器)→01000001(存儲器);
因此,一樣的位模式可表示數字,字符或者圖像等不一樣的場景,例如上面的兩個例子,一樣是01000001經過不一樣的程序表現出來的東西是不同的,而計算機在進行存儲東西的時候不須要辨別他們表示的是什麼樣的數據類型;
存儲數字:
數字在存儲到計算機內存以前,要經過進制轉換(即轉換成二進制),這裏就不說進制轉換的問題了,而在日常生活中數字有整數,小數,正負之分等問題,計算機使用兩種不用的方式:定點和浮點法;
1:存儲整數(整數是完整的數字,是沒有小數部分的),例如 134 ,-145;
首先假設存儲單元的最右邊有一個小數點(實際上在計算機中是不存在),整數一般使用定點法存儲在內存中;
但學過C語言的都知道整數類型分爲兩大類,第一類爲無符號(0和正數的非負整數),第二類爲有符號(即有正有負);
1.1無符號表示法(存儲無符號整數)
因爲不可能表示0到無窮大的全部整數,因此計算機一般會定義一個常量,這個常量被稱爲 最大無符號整數 ,它的值是2的n次方-1,這裏的n是計算機分配用於表示無符號整數的二進制位數,例如:n的位數爲4,它能表示的最大無符號整數就爲15;
存儲無符號整數有以下幾個步驟:①將整數轉化爲二進制 ②若是二進制的位數不足n位,就在二進制的左邊補0,使整數的位數與二進制的位數相等;若是大於轉換後的整數的二進制位數大於n,那就會發生溢出的狀況,咱們後面將討論溢出的狀況,在這裏不過分敘述;
例如:將數字7存儲在8位的存儲單元中,使用無符號表示法:
①將7轉換爲二進制1 1 1 ②在左邊進行補0,湊成 0 0 0 0 0 1 1 1 ,共8位,因此數字7在計算內存中就爲0 0 0 0 0 1 1 1;
若是是16位,那就補夠0到16位,以此類推;
接下來,咱們說一說溢出的問題:咱們在寫程序的時候若是數據發生溢出,就會致使結果不正確,這種結果致使的後果是小的,也多是大的;
其實致使溢出的根本緣由是 受存儲單元的位數 的限制,因此表達整數的範圍也是有限的,接下來,咱們引出一個例子來講明這個問題;
這是一個時鐘的錶盤,它能所表示的最大整數爲12,一旦超過12,就會從1從頭開始,因此在這個錶盤中表示3這個數,有無數種方式,即3,15,27......,(由於咱們討論的是無符號的存儲,因此不考慮負數的狀況,即-8...也可表示3);
因此在計算機中的n位存儲單元中,就把其想象成爲一個無限循環的錶盤,假設有一個4位的存儲單元,它能存儲的無符號整數的範圍爲0到15,此時有個整數11,加上個9,此時,咱們但願看到的結果爲20,可是20超過了4位存儲單元所能表示的最大整數,計算機得出的結果爲4,下圖解釋了爲何是4的緣由;
無符號整數表示法能夠提升存儲的效率,由於不用去考慮符號的問題。這就意味着全部分配到的存儲單元均可以用來存儲數字,只要用不到負整數就能夠用無符號整數表示法;
1.2符號加絕對值表示法
其實在存儲整數中這種方法並不經常使用,但該格式在存儲部分實數的很經常使用,因此在這裏討論一下這種方法,請認真的看完會給你接下來的學習有幫助。
在此方法中,用於無符號整數的有效範圍(0~2的n次方-1)被分爲兩個相等的子範圍,前半段用於表示整數,後半段用於表示負數,假如,此時的n爲4,那麼表示的範圍就是0000到1111,把它分爲兩部分:即正整數部分爲:0000到0111,負整數部分爲1000到1111;
在理解這種位模式須要有如下注意的地方:①負數在右邊(在數學的數軸上表示爲負數在左)②該表示法中有兩個0,有個正0,一個負0;
在用符號加絕對值表示法存儲一個整數的時候,須要用一個二進制位來表示符號(0表正,1表負),這就意味着在一個八位的存儲單元中,用於存儲數字的實際上只有7位,所以,該表示法的最大正數值爲無符號最大數一半,因此在n位單元的可存儲數字的範圍爲 ﹣(2的n-1次方-1)到 +(2的n-1次方-1);
例如:用符號加絕對值法將+28存儲到8位的存儲單元中
解:①現將該整數轉換爲二進制11100,由於要用最左邊的一個二進制來表示符號,因此補0至7位,因此獲得 0 0 1 1 1 0 0;
②再將左邊的符號位補上,由於該數爲正,因此左邊補0;
若是是負的28呢?若是用符號加絕對值法將存儲的 0100110一、10100001復原成整數呢?請自行計算,答案爲:10011100,+77,-33;
咱們在上面提到過在存儲無符號正數的時候會發生溢出(正數溢出),一樣在存儲有符號整數的時候一樣會發生溢出,與上面不一樣的是它將發生兩種溢出(正溢出和負溢出);
同上面同樣咱們依舊把其想象成爲一個循環的錶盤,不一樣的是在這個錶盤中有正數和負數之分,並且有兩個0;
假設:有一個4位的存儲單元,用符號加絕對值表示法來表示溢出狀況
咱們這時保存一個整數5在存儲單元中,又試圖加上個6,這時就會發生溢出的狀況,咱們看下圖:
以上計算,咱們所指望的結果爲11,計算機相應的-3;由於在一個循環的表示中,7是4位存儲單元所能表示的最大正整數,而11超出了7,因此獲得的結果爲3,注意,-0也做爲相加的一個數,千萬不能忘記;一樣的,負溢出也是如此;
一般狀況下,符號絕對值法不用於存儲整數,而用於部分實數,因此學習以上會對你學存儲實數有很大的幫助,另外,符號加絕對值表示法一般用於採樣模擬信號,例如,音頻。
1.3二進制補碼錶示法(現現在幾乎全部的計算機都使用二進制補碼法來存儲位於n位存儲單元的有符號整數,因此它很重要)
在二進制補碼法中,同符號加絕對值法相同,它將無符號整數的有效範圍(0~2的n次方-1)分爲兩個相等的子範圍,但與上面不一樣的是,第一個子範圍用來表示非負整數,而第二個子範圍用於表示負整數,並且只有一個0;
例如:若是n爲4,該範圍是0000到1111,分兩半即0000到0111 和 1000到 1111,而後按照左負右正的原則進行排放,以下圖所示:
在二進制補碼錶示法中,最左位決定符號,若是爲0,則爲正,1則爲負;
在深刻探討這種表達法以前,咱們先引入兩個反碼和補碼這兩種運算,反碼就是將各個位進行反轉,即0變1,1變0;
例如:求整數00110110的反碼
第二個爲整數的補碼:正數(包括0)的補碼是它自己,也就是不作補碼運算,而負數的補碼運算有兩種,這裏,咱們介紹一種簡單的補碼運算。
該運算分爲兩步,第一步,從二進制數右邊進行復制,一直到第一個1出現(將1複製下來),而後反轉其他位,以下圖所示:
這樣就獲得了該數的補碼,計算機在以二進制補碼存儲整數的時候:遵循如下步驟:①將整數變成n位的二進制數,若是是0或正數,則按原樣存儲,負數,就要取其補碼存儲,
可能到這裏,你可能會有疑慮,爲何要費時間作這種無聊的事,其實緣由很簡單:方便計算,由於該篇文章只說存儲,因此你只要知道補碼的概念和運算就好了,至於另外一種補碼的運算是:取其二進制數的反碼,而後在作加一的運算,也可獲得反碼。
咱們下面作一下二進制反碼錶示法的運算:
例:將28存儲在8位存儲單元中
解:由於28是正數,因此補碼就是是其二進制原樣,因此爲 0 0 0 1 1 1 0 0(注意這裏要進行補0)
例:將-28存儲在8位存儲單元中
解: 由於該整數爲負,因此要取其二進制數的補碼,原碼爲 0 0 0 1 1 1 0 0,進行補碼運算後就爲1 1 1 0 0 1 0 0
還原整數按照反方向計算便可;
在二進制補碼法中最有趣的是符號位的0或1也參與運算, 並且該表示法僅有一個0,符號加絕對值法有兩個0。
在最後就是溢出問題了,同其餘表示法相同,二進制補碼錶示法一樣會發生溢出,且有正負兩種溢出
假設有4位存儲單元,當咱們保存整數5在存儲單元中,在加上6,指望結果爲11,結果爲-5,以下圖所示:
要注意的是該表示法只有一個0,同理,負數的溢出也是如此。
當今,二進制補碼法是計算機存儲整數的標準表示法,由於它能給運算帶來很大的便利。
2:存儲實數(實數即帶有整數部分和小數部分的數字)例如23.7
儘管固定小數點法能夠用於表示實數,到實際上可能會致使數據丟失,從而達不到所須要的進度。
例如:咱們用小數點左邊爲14個碼數,右邊爲2個碼數,共16個碼數的定點表示法,再存儲1.00324,精度就會受損,實際存儲爲1.00。
所以帶有很大的整數部分或很小的小數部分適不適合用定點法來存儲的,應該用浮點表示法。
浮點表示法由三部分組成:符號,位移量,定點數,使用這種方法存儲可以表示很大或很小的數,從而保證了實數的精度。
符號位:0爲正,1爲負;
位移量位:在下面的餘碼系統中會說明;
定點數:小數點位置固定的定點表示法;
2.1科學表示法
科學表示法在表述很大或很小的數時,形式更短更簡潔,例如230000.00,用科學計數法就爲2.3*10^5;
由於日常生活計算都是十進制,因此該方法引伸到計算機存儲中,即爲01形式,且以2爲底數,例如:101110.1,用科學計數法表示就爲1.01101*2^4;負數同理;
2.2規範化
在這種規範化中,在小數點的左邊都使用了惟一的非零數碼,再十進制的系統中的數碼多是1到9,而二進制系統中的數碼爲1,以下圖:
2.3符號、指數和尾數
在將一個二進制數規範化以後,咱們會存儲了一個數的三部分信息,也就是指數和尾數,下圖是一個規範化後的例子:
符號是用來存儲正負的;指數是定義爲小數點移動的位數;尾數就是小數點右邊的二進制數;
2.4餘碼系統
在存儲尾數的時候實際上能夠把它當作一個無符號的數看待,可是指數就不行了,由於指數有正負之分,在上面咱們提到過用補碼法來存儲有符號的整數,但實際在存儲實數的過程當中,採用了一種叫餘碼系統的表示方法來代替補碼法。
在餘碼系統中,正數和負數均可以做爲無符號數存儲,但爲了表示正負的整數,一個正整數(稱爲一個偏移量)加到每一個數字中,將他們移到非負的一邊,這個偏移量的計算方法是2的m-1次方-1,m爲內存單元的大小。
例如在四位存儲單元中可表示16個整數,即-7到8,若是在該範圍中加7個單位,就能夠把它們統一的往右移將其變爲正數,這種新系統稱爲餘7或偏移量爲7的偏移表示法;
這種新的表示法與移位前相比,優勢在於全部的整數都是正數,在進行運算的時候不用考慮符號。
2.5存儲浮點數
說到存儲浮點數,就要提到IEEE所規定的的標準了,這裏只討論兩種最經常使用的——單精度和雙精度。
單精度格式採用總共32位來存儲一個浮點表示法的實數。符號佔1位,指數佔8位,尾數佔23位,此標準餘127碼,也就是2的m-1次方-1,所以,偏移量爲127;
雙精度格式採用總共64位來存儲一個浮點表示法的實數。符號佔1位,指數佔11位,尾數佔52位,此標準餘1023碼,也就是2的m-1次方-1,所以,偏移量爲1023;
說了以上這麼多,都是爲了更好的學習計算機是如何存儲實數的,下面將介紹存儲實數的具體步驟:
①在S中存儲符號(0或者是1);
②將數字轉換爲二進制;
③規範化;
④找到E和M的值
⑤鏈接S、E和M;
例:寫出十進制數5.75的餘127碼(單精度)表示法
解:(1)符號爲正,因此S=0;(2)十進制轉二進制爲 5.75=101.11;(3)規範化:101.11=1.0111*2^2;(4)E=127+2=129=10000001,M=0111,還須要在M的右邊補19個0,讓它變成23位;(5)連接S、E、M、,因此實數5.75存儲在計算機中的實際數是0 10000001 01110000000000000000000。
負數也是如此,這裏就很少說了,你們能夠本身作一作練習;
最後在這裏談一談如何獲得單精度的最大值與最小值:咱們能夠在網上或者書籍能看到四字節的單精度float類型的範圍約爲:-3.4*10^38~3.4*10^38;
在這裏先要說明兩個小細節,由於8位存儲單元索所能表示的最大正數爲255,但IEEE754規定0和255用於表達特殊值,因此float指數的實際範圍爲-126到+127,具體的能夠本身搜索IEEE754;
因此float類型的最大值就爲:1.11111111...1(小數部分共23位)*2^127約等於3.4*10^38;最小值就爲1.00000....1(小數部分共23位)*2^-126約等於-3.4*10^38;
存儲文本:
在任何語言中,文本的片斷是用來表示該語言中某個意思的一系列符號。例如英語中用A~Z表大寫,a~z表小寫,還有數字和符號等;
所以,咱們就能夠用位模式來表示任何一個符號。例如4個符號組成的文本 「CATS」能用4個n位模式表示,任何一個模式定義一個單獨的符號;
那麼問題來了,在某一種語言中,位模式要多大來表示一個符號?這就取決於該語言集到底有多少個不一樣的符號。假設,咱們如今建立一種語言,只有大寫英文字母一共26個,因此這種語言的位模式至少須要表示26個符號;
位模式的長度取決於符號的數量,他們的關係是呈對數的。例如,須要2個符號,位模式的長度就爲:log2^2=1;須要四個就爲:log2^4=2;
在2位的位模式下,共有00,01,10,11四種形式,這些形式的任何一種都能表明一個字符,例如00能夠規定爲:a,b或者是字符?,均可以;
這也就解釋了爲何以%d形式輸出字符,實際上輸出的是數字,例如:字符0,以十進制輸出爲48;
下圖表爲符號數量和位模式長度的關係:
不一樣的位模式集合被設計用於表示文本符號,其中每個集合咱們稱之爲代碼,表示符號的過程稱爲編碼,下面介紹兩個很常見的編碼:
1 :ASCII
ANSI(美國國家標準協會)開發了一個被稱爲美國信息交換標準碼的代碼,該代碼使用7位表示每一個符號,該代碼可表示2^7=128種不一樣的符號,具體請自行搜索;
2:Unicode
硬件和軟件製造商一塊兒聯合設計了一種名爲Unicode的代碼,這種代碼使用32位能表示的最大符號數量爲2^32,這種代碼不一樣部分被分配用於表示來自世界上不一樣語言的符號,現現在ASCII是Unicode的一部分。
存儲音頻:
音頻表示音樂或者是聲音,音頻本質上與咱們討論的數字,文本都不一樣:由於音頻是不可數的;
音頻是隨時間變化的實體,所以,咱們只能測出每一時刻聲音的密度,因此計算機在進行存儲音頻的時候也是按照密度進行存儲的,例如每隔一秒或兩秒;
音頻是模擬數據的例子,咱們就算可以獲得一段時間的全部值,可不能把它們所有存儲起來,這意味着須要無限個存儲單元,顯然這是不顯示的,下圖顯示了一個音頻信號:
存儲音頻第一步:
①採樣:咱們要從一段時間內選擇數量有限的點來度量它們的值並記錄下來,例如記錄一秒鐘內的10個樣本:
接下來就是採樣率的問題了,意思每秒鐘要採集多少個樣本才能還原出原始信號的副本,樣本數量依賴於模擬信號中變化的最大值,換句話說,若是信號平坦的,就須要不多的樣本,反之,就須要更多,通常來講每秒40 000個樣本的採樣率對於音頻信號來講足夠了;
②量化:每一個樣本測來的值都是真實的數字,這意味着咱們要爲每一秒的樣本存儲40 000個真實的值,由於樣本的值多是17.2等實數,所以在實際存儲中會爲每個值當成無符號存儲(由於存儲數量是有符號的兩倍),經過量化進行截取(量化:將樣本的值截取爲最接近整數值的一種過程),例如17.2,就可截取爲17;
③編碼:量化後的樣本值須要被編碼成位模式,有些系統會爲樣本附正值或者是負值,而有一些會使用無符號的整數來表示樣本,但通常有符號的整數不會用補碼法來表示,而是用符號加絕對值法,這在上面也提到過;
每樣本位:對於每一個樣本系統須要決定分配多少位,如今通常都爲16 、2四、或者是32,每樣本位的數量有時稱爲深度;
位率:把深度的數量稱爲B,把每秒樣本數稱爲S,咱們須要爲每秒的音頻存儲S*B位,乘積稱爲位率R。例如:每秒40 000個樣本,深度爲16位,
位率R=40 000*16=640 000b/s=640KB/s。
當今主流的音頻編碼標準爲MP3,它每秒採起44100個樣本以及每樣本16位,再用去掉那些人耳沒法識別的信息進行壓縮,這是一種有損壓縮法,還有一種爲無損。
存儲圖像:
由於不過重要,實在是不想寫了,因此截了圖。。。。
存儲視頻:
視頻是圖像(稱爲幀)在時間上的表示。一部電影就是一系列的幀一張接着一張地播放而運動造成的圖像,將圖像或幀轉化爲一系列的位模式並存儲,組合起來就成爲了視頻,如今視頻一般是被壓縮存儲的,常見的有MPEG。
以上內容絕大部分參考了計算機科學導論這本書,我學習後,按照本身的理解進行講述,因此,有不對的地方,請指出。