計算機系統是如何存儲整數、小數、正數、負數的

計算機對外信息展現方式有文字、圖片、音頻、視頻等,但不論應用在什麼地方,信息在機器內部的形式都是一致的,即均爲0和1組成的各類編碼。html

1、有符號數和無符號數

在計算機中參與運算的數有兩大類:無符號數和有符號數。java

無符號數

計算機中的數均放在寄存器中,一般稱寄存器的位數爲機器字長。編程

所謂無符號數,即沒有符號的數,在寄存器中的每一位都可用來存放數值。當存放有符號數時,則需留出位置存放符號。編碼

所以,在機器字長相同時,無符號數與有符號數所對應的數值範圍是不一樣的。3d

以機器字長爲16位爲例,無符號數的表示範圍爲 0~65535,而有符號數的表示範圍爲 -32768 ~ +32767(此數值對應補碼錶示)。code

有符號數

對有符號數而言,符號的「正」、「負」機器是沒法識別的,但因爲「正」、「負」剛好是兩種大相徑庭的狀態,若是用「0「表示「正」,用「1」表示「負」,這樣符號也被數字化了,而且規定將它放在有效數字的前面,即組成了有符號數。
例如,+1100 在機器中表示爲 01100 ,-1100 在機器中表示爲 1 1100 。視頻

在Java語言中,如 int、float 等都是有符號數,故下文所講都是在有符號數的範疇。htm

2、機器數與真值

把符號(如+、-)「數字化」的數稱爲機器數,而把帶「+」或「-」符號的數稱爲真值blog

一旦符號數字化後,符號和數值就造成了一種新的編碼。在運算過程當中,符號位可否和數值部分一塊兒參加運算?若是參加運算,符號位又需做哪些處理?這些問題都與符號位和數值位所構成的編碼有關,這些編碼就是原碼、補碼、反碼和移碼。圖片

原碼

原碼是機器數中最簡單的一種表示形式,符號位爲0的表示正數,符號位爲1的表示負數,數值位即真值的絕對值,故原碼錶示又稱爲帶符號的絕對值表示。

反碼

正數的反碼依舊等於原碼,負數的反碼是在其原碼的基礎上, 符號位不變,其他各個位取反。

補碼

正數的補碼碼依舊等於原碼,負數的補碼是在其原碼的基礎上, 符號位不變, 其他各位取反, 最後+1。 (即在反碼的基礎上+1)

移碼

同一個真值的移碼和補碼僅差一個符號位,若將補碼的符號位由「0」改成「1」,或從「1」改成「0」,便可得該真值的移碼。簡單說,不管正負數,只要將其補碼的符號位取反便可。

3、定點數與浮點數

在計算機中,小數點不用專門的器件表示,而是按約定的方式標出,共有兩種方法表示小數點的存在,即定點表示和浮點表示。定點表示的數稱爲定點數如 java 語言中的 int),浮點表示的數稱爲浮點數如 java 語言中的 float、double)。

定點數

小數點固定在某一位置的數爲定點數,有如下兩種格式。


當小數點位於數符和第一數值位之間時,機器內的數爲純小數;當小數點位於數值位以後時,機器內的數爲純整數

採用定點數的機器稱爲定點機。數值部分的位數n決定了定點機中數的表示範圍。若機器數採用原碼,小數定點機中數的表示範圍是 -(1 - 2^-n) ~ (1 - 2^-n),整數定點機中數的表示範圍是 -(2^n-1) ~ (2^n-1)。

浮點數

實際上計算機中處理的數不必定是純小數或純整數(如圓周率3.1416),並且有些數據的數值範圍相差很大(如電子的質量9×10-6g,太陽的質量2×103g),它們都不能直接用定點小數或定點整數表示,但都可用浮點數表示。浮點數即小數點的位置能夠浮動的數,如

352.47 = 3.5247 * 10^2 = 3524.7 * 10^-1

顯然,這裏小數點的位置是變化的,但由於分別乘上了不一樣的 10 的方冪,故值不變。

一般,浮點數被表示成 N = S * r^j , 式中,S爲尾數(可正可負),j爲階碼(可正可負),r是基數(或基值)。在計算機中,基數可取2,四、8或16等。

浮點數的規格化形式爲 N = 0.110101 * 2^10。

浮點數在機器中的形式以下所示。

浮點數由階碼j和尾數S兩部分組成。階符表示階碼數值部分的正負,數符表示尾數數值部分的正負。階碼j反映了浮點數的表示範圍及小數點的實際位置。尾數是小數,其位數n反映了浮點數的精度。

定點數與浮點數的比較

定點數和浮點數可從以下幾個方面進行比較。

①當浮點機和定點機中數的位數相同時,浮點數的表示範圍比定點數的大得多。

②當浮點數爲規格化數時,其相對精度遠比定點數高。

③浮點數運算要分階碼部分和尾數部分,並且運算結果都要求規格化,故浮點運算步驟比定點運算步驟多,運算速度比定點運算的低,運算線路比定點運算的複雜。

④在溢出的判斷方法上,浮點數是對規格化數的階碼進行判斷,而定點數是對數值自己進行判斷。例如小數定點機中的數其絕對值必須小於1,不然「溢出」,此時要求機器中止運算,進行處理。爲了防止溢出,上機前必須選擇比例因子,這個工做比較麻煩給編程帶來不便。而浮點數的表示範圍遠比定點數大,僅當「上溢」時機器才中止運算,故通常沒必要考慮比例因子的選擇。

總之,浮點數在數的表示範圍、數的精度、溢出處理和程序編程方面(不取比例因子)均優於定點數。但在運算規則、運算速度及硬件成本方面又不如定點數。所以,究竟選用定點數仍是浮點數,應根據具體應用綜合考慮。通常來講,通用的大型計算機大多采用浮點數,或同時採用定、浮點數;小型、微型及某些專用機、控制機則大多采用定點數。當須要做浮點運算時,可經過軟件實現,也可外加浮點擴展硬件(如協處理器)來實現。

4、IEEE 754標準

現代計算機中,浮點數通常採用 IEEE 制定的國際標準,這種標準形式以下:

按 IEEE 標準,經常使用的浮點數有三種:

符號位S 階碼 尾數 總位數
短實數 1 8 23 32
長實數 1 11 52 64
臨時實數 1 15 64 80

其中,S爲數符,表示浮點數的正負,但與其有效位(尾數)是分開的。

階碼的真值都被加上一個常數(偏移量),如短實數、長實數和臨時實數的偏移量用十進制數表示分別爲 12七、1023 和 16383。

尾數部分一般都是規格化表示,即寫成 1.xxxxxx 的形式,其中 xxxxxx 表示小數部分。IEEE 754規定,在計算機內部保存尾數時,默認這個數的第一位老是1,所以能夠被捨去,只保存後面的xxxxxx部分。

下面列出了十進制數 178.125 的實數表示。

實數表示 數值
原始十進制數 178.125
二進制數 10110010.001
二進制浮點表示 1.0110010001*2^111
符號 偏移的階碼 有效值
短實數表示 0 0000 0111+0111 1111
=1000 0110
0110 0100 0100 0000 0000 000

注:二進制浮點數的基數是2;基數2的指數111是未偏移的階碼;有效值只保留了尾數的小數部分0110010001。

你也能夠編寫 java 程序來驗證在機器上浮點數是不是以 IEEE754 標準存儲的,示例代碼以下:

@Test
public void test(){
    int i = Float.floatToIntBits(178.125f);
    System.out.println(Integer.toBinaryString(i));
    //0 10000110 01100100010000000000000(符號+偏移的階碼+有效值)
}

推薦文章

[1] 浮點數的二進制表示 阮一峯

相關文章
相關標籤/搜索