跳轉到內容

資料表示基礎:浮點數

來自華夏公益教科書

論文 2 - ⇑ 資料表示基礎 ⇑

← 範圍和精度 浮點數 浮點數標準化 →


如果你學習了物理或化學等其他學科,你可能會遇到這樣的浮點數

  (Planck's constant)

第一位定義了數字的非零部分,稱為尾數,第二部分定義了我們要移動小數點的位數,這被稱為指數,當小數點向右移動時可以是正數,當小數點向左移動時可以是負數。

如果你想完整寫出這個數字,你需要在指數中將小數點向左移動 34 位,得到


這將花費很多時間來寫,而且人眼很難看清有多少個零。因此,當我們可以接受一定程度的精度(6.63 = 3 位有效數字)時,我們可以用少數位數儲存像普朗克常數這樣的多位數。你總是權衡數字的範圍(或範圍)與其精度(有效位的數量)。

二進位制數也是如此,而且更為重要。在處理數字及其計算表示時,你必須始終注意這些數字在記憶體中會佔用多少空間。正如我們在上面的例子中看到的,一個數字的非浮點表示可能佔用不可接受的位數,想象一下,你需要用多少位來儲存 在二進位制中‽

一個二進位制浮點數可能包含 2、3 或 4 個位元組,但是你只需要關注 2 位元組(16 位)的型別。前 10 位是尾數,後 6 位是指數。

就像十進位制('基數 10','十進位制')浮點數表示一樣,二進位制浮點數將有一個尾數和一個指數,但由於你正在處理二進位制(基數 2),你必須記住,你不是使用 ,而是必須使用 .

為什麼要使用二進位制浮點數

[編輯 | 編輯原始碼]

定點二進位制允許計算機儲存小數,但由於其性質,其範圍非常有限。即使使用 4 個位元組來儲存每個數字,並將小數點後的分數部分用 8 位表示,可以儲存的最大數字也只有 800 多萬。需要另一種格式來儲存非常大的數字。

在十進位制中,可以用尾數和指數來表示非常大的數字。例如 0.12*10²。這裡的 0.12 是尾數,而 10² 是指數。尾數儲存主要數字,而指數定義了小數點應該放置的位置。

相同的技術可以用於二進位制數。例如,可以將兩個位元組分成 10 位用於尾數,剩餘的 6 位用於指數。這允許使用更大範圍的數字。

將二進位制浮點數轉換為十進位制

[編輯 | 編輯原始碼]

在計算二進位制浮點數時,需要經過幾個步驟。事實上,這很像迪斯科舞曲的舞蹈套路 - 在這個頁面上被稱為 Noorgat 舞蹈,Kemp 變奏(你不會被考查名稱,但它應該能幫助你記住)

  1. 符號 - 找到尾數的符號(記下來)
  2. 滑動 - 找到指數的值,以及它是正還是負
  3. 反彈 - 根據指數的要求移動小數點,負指數向左移動,正指數向右移動
    1. 如果向左移動並且是正數,則用零填充
    2. 如果向左移動並且是負數,則用一填充
  4. 翻轉 - 如果尾數為負數,則對其進行二進位制補碼運算
  5. 遊動 - 從小數點開始,從左到右計算尾數的值。現在確保你參考你在符號移動中記錄的符號。
示例:二進位制浮點數示例

讓我們試一試。我們給定以下 16 位浮點數,其中 10 位用於尾數,6 位用於指數。請記住,小數點位於第一位和第二位有效位之間



我們需要執行的第一個操作是 符號,找出尾數的符號


It is 0 so the mantissa is positive

Noorgat 舞蹈的第二步是 滑動,我們需要找到指數的值,即數字的最後 6 位



So we know that the exponent is of size positive one and we will have to move the decimal point 
one place to the right.

Noorgat 舞蹈的第三步是 反彈,即將尾數的小數點移動由滑動指定的位數,在本例中是向右移動一位。就像這樣



第四步是可選的 翻轉。檢視符號階段並檢視尾數是否為負數。不是嗎?好吧,你可以跳過這一步,因為我們只在尾數為負數時翻轉數字。

第五步也是最後一步是 遊動。單獨考慮尾數,我們可以現在計算出浮點數的值。從中心開始,將左側的每個數字標記為 等等。右側的每個數字 等等。



Voila! the answer is 1
練習:簡單二進位制浮點數

使用 10 位尾數和 6 位指數計算以下數字的十進位制值

0.001101000 000110

答案

1. 符號:尾數以零開頭,因此它是一個 正數
2. 滑動:計算指數的值

000110 = +6

3. 反彈:我們需要移動尾數中的小數點。在本例中,指數為 ,因此我們需要將小數點向右移動 6 位

0.001101000 -> 0001101.000

4. 翻轉:由於數字不是負數,因此我們不需要這樣做
5. 遊動:計算小數點左側和右側的值

1+4+8 = +13 FINISHED!

0 101000000 111111

答案

1. 符號:尾數以零開頭,因此它是一個 正數
2. 滑動:計算指數的值

111111 It starts with a one therefore it is a negative number
000001 = -1

3. 反彈:我們需要移動尾數中的小數點。在本例中,指數為 ,因此我們需要將小數點向左移動 1 位

0.101000000 -> 0.0101000000

4. 翻轉:由於尾數不是負數,因此我們不需要這樣做
5. 遊動:計算小數點左側和右側的值

1/4 + 1/16 = +0.3125 FINISHED!

1 011111010 000101

答案

1. 符號:尾數以 1 開頭,因此它是一個 負數
2. 滑動:計算指數的值

000101 = +5

3. 反彈:我們需要移動尾數中的小數點。在本例中,指數為 ,因此我們需要將小數點向右移動 5 位

1.011111010 -> 101111.1010

4. 翻轉:尾數為負數,如步驟 1 中所述,因此我們需要轉換此數字

101111.1010 -> 010000.0110

5. 遊動:計算小數點左側和右側的值

16+1/4+1/8 = -16.375 FINISHED!

1 101000000 111101

答案

1. 符號:尾數以 1 開頭,因此它是一個 負數
2. 滑動:計算指數的值

111101 It starts with a one therefore it is a negative number
000011 = -3

3. 反彈:我們需要移動尾數中的小數點。在本例中,指數為 ,因此我們需要將小數點向左移動 3 位。仔細觀察!

1.101000000 -> 1.111101000000
note that we placed extra ones on the front of the number.
Consider the exponent being negative and the mantissa positive, we would add extra zeros on the front 0.01 * 2^-3 = 0.00001
If both are negative placing zeros in front of the mantissa would make it positive!
Therefore, we need to add extra ones to keep the mantissa negative
With the flip we'll lose these 'extra' ones

4. 翻轉:尾數為負數,如步驟 1 中所述,因此我們需要轉換此數字

1.111101000000 -> 0.000011000000

5. 遊動:計算小數點左側和右側的值

1/32+1/64 = -0.046875 Remember the number was negative! FINISHED!

1 111111010 000011

答案

1. 符號:尾數以 1 開頭,因此它是一個 負數
2. 滑動:計算指數的值

000011 = +3

3. 反彈:我們需要移動尾數中的小數點。在本例中,指數為 ,因此我們需要將小數點向右移動 3 位。

1.111111010 -> 1111.111010

4. 翻轉:尾數為負數,如步驟 1 中所述,因此我們需要轉換此數字

1111.111010-> 0000.000110

5. 遊動:計算小數點左側和右側的值

1/16+1/32 = -0.09375 Remember the number was negative! FINISHED!

將十進位制數轉換為二進位制浮點數

[編輯 | 編輯原始碼]

你可能還會被要求將一個十進位制數轉換為其二進位制浮點數等效值。

  1. 計算二進位制等效值
  2. 計算移動二進位制小數點的距離 (y)
  3. 將指數設定為移動二進位制小數點的位數的反向 (-y)
  4. 用額外的位填充數字
示例:十進位制數轉換為二進位制浮點數

如果我們被要求將十進位制數 39.75 轉換為二進位制浮點數,我們首先需要找出二進位制等效值

128 64 32 16  8  4  2  1 . ½  ¼  ⅛
  0  0  1  0  0  1  1  1 . 1  1  0 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

  0  0 . 1  0  0  1  1  1  1  1  0  (6 places to the left)

因此,為了使小數點回到它開始的位置,我們需要將它向右移動 6 位。6 現在成為你的指數。

0.100111110 | 000110

如果你想檢查你的答案,將上面的數字轉換為十進位制數。你會得到 39.75!


練習:簡單二進位制浮點數

使用 10 位尾數和 6 位指數計算以下數字的二進位制浮點數

67

答案

128 64 32 16  8  4  2  1 . ½  ¼  ⅛
  0  1  0  0  0  0  1  1 . 0  0  0 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

  0 . 1  0  0  0  0  1  1  0  0  0  (7 places to the left)

為了使前部標準化,我們必須將小數點移動 7 位。(將它移動 6 位會使數字變為負數!)

0.100001100 | 000111

23.25

答案

128 64 32 16  8  4  2  1 . ½  ¼  ⅛
  0  0  0  1  0  1  1  1 . 0  1  0 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

  0  0  0 . 1  0  1  1  1  0  1  0   (5 places to the left)

為了使前部標準化,我們必須將小數點移動 5 位。(將它移動 4 位會使數字變為負數!)

0.101110100 | 000101

123.875

答案

128 64 32 16  8  4  2  1 . ½  ¼  ⅛
  0  1  1  1  1  0  1  1 . 1  1  1 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

  0 . 1  1  1  1  0  1  1  1  1  1   (7 places to the left)

為了使前部標準化,我們必須將小數點移動 7 位。

0.1111011111 | 000111

但這使用的是 11 位尾數,我們必須捨棄一位,從而損失精度!

0.111101111 | 000111

128.25

答案

128 64 32 16  8  4  2  1 . ½  ¼  ⅛
  1  0  0  0  0  0  0  0 . 0  1  0 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

0.1  0  0  0  0  0  0  0  0  1  0   (8 places to the left)

為了使前部標準化,我們必須將小數點移動 8 位。(將它移動 7 位會使它變為負數!)

0.100000000 | 001000

請注意,我們必須捨棄 .25,因為它不適合 10 位尾數。

-513

答案

1024 512 256 128 64 32 16  8  4  2  1 . ½  ¼  ⅛
   0   1   0   0  0  0  0  0  0  0  1 . 0  0  0 

使用翻轉規則將其轉換為負數形式

1024 512 256 128 64 32 16  8  4  2  1 . ½  ¼  ⅛
   1   0   1   1  1  1  1  1  1  1  1 . 0  0  0 

我們需要將二進位制小數點向左移動多少位才能使數字標準化?

   1 . 0  1  1  1  1  1  1  1  1  1  0  0  0   (10 places to the left)

為了使前部標準化,我們必須將小數點移動 10 位。

1.011111111 | 001010

請注意,我們必須捨棄最後一個 1,因為它不適合 10 位尾數。這意味著顯示的數字只是

10111111110.0

將其轉換為十進位制數

01000000010.0 = -514

你很快就會了解使用浮點數的誤差

當你有一個 16 位數字,其中尾數為 10 位,指數為 6 位時

最大正數將是

Mantissa: 0.111111111
Exponent: 011111

最小正數將是

Mantissa: 0.000000001
Exponent: 100000

最大負數將是

Mantissa: 1.000000000
Exponent: 011111

最小負數將是

Mantissa: 1.111111111
Exponent: 100000
華夏公益教科書