儲存整數的方法,在電腦裡負數是如何表示的

歡迎你點入本篇文章,會促成我想做這篇的原因,主要是因為在上計概時,突然浮現很多靈感,跟一大堆的問題(教授,為什麼要講的這麼淺白呢?我想知道更多啊啊!),為了一次解決我所有的困惑,於是製作本篇文章。

另外本篇偏向於做題篇,原理部分可能點到為止。

若文章有任何疑點及錯誤的地方歡迎提出。

上一篇文章:淺談二進位與十六進位,為什麼電腦要使用?你所不知道的二進位。

Sign–magnitude representation(原碼表示法)

這種方法可以顯示 $2^n - 1$ 個無號整數(unsigned integer)。

無號整數(unsigned integer)

所謂無號整數亦即 >= 0 的整數,這種整數儲存方式很簡單,只要把十進位轉換成二進位即可。

如:將 7 轉成 8 bit(位元)的整數。

7 的二進位是 $(111)_2$ ,要轉成 8 bit 就在前面補 0,變成: $(00000111)_2$ 即可。

在 8 bit 的系統裡面,如果 $(11111111)_2 + (00000001)_2$ ,這兩個相加之後,會變成 $(00000000)_2$ ,也就是我們所知的溢位(overflow),就是這樣子來的。

有號整數(signed integer)

要表示一個有號整數,可以讓最左邊的位元充當正負號。

bit+ / -
0+
1-

如 +28 的 8 位元就可表示成: $(00011100)_2$ 。

最左邊的 0 表示這個 28 是個正數。

如果是 -28 的 8 位元,則表示成: $(10011100)_2$ 。

在 Sign–magnitude representation 的缺點就是,會出現一個 +0 $(00000000)_2$ 跟 -0 $(10000000)_2$ ,並且正負之間的位元相加會產生錯誤。

如 +1 跟 -1 做相加: $(00000001)_2 + (10000001)_2 = (10000010)_2$

而 $(10000010)_2$ 轉成十進位就是 -2,很明顯不是我們要的答案。

Two’s complement representation(二補數表示法)

剛剛講解了 Sign–magnitude representation 的原理,他的缺點就是會有 +0 跟 -0,並且正負數相加會產生錯誤。

為了解決這個問題,所以我們聰明的電腦科學家們發明了二補數表示法(Two’s complement representation)。

順便講個小故事:馮·諾伊曼(von Neumann)是把這套數字系統在電腦科學中發揚光大的一名科學家。

二補數表示法也是現在電腦採用的系統,因為它能把減法運算這個東東用加法電路來實現,簡化了硬體設計。

如何做二補數表示法?

二補數的計算方式:

  1. 先做 One’s complementing (一補數)(將所有位元反轉)
  2. 再加 1

另外所謂的補數就是把所有位元裡面的 0 變成 1,1 變成 0。

舉例

Question : 求 -5 的 8 bit 二補數表示法

首先找出 +5 的二進位(8 bit): $(00000101)_2$ 。

再來做一補數的動作:$(00000101)_2 → (11111010)_2$ 。

再把這個一補數給加上 1:$(11111010)_2 + (00000001)_2 = (11111011)_2$ 。

我們最後得到的結果 $(11111011)_2$ 就是 -5 在 8 bit 的二補數表示法了。

驗證

我們可以試試看把 -5 跟 +5 在二補數表示法中給他加起來,看會不會是 0。

$(11111011)_2 + (00000101)_2 = (00000000)_2$

最後你會發現加到最後那個 1 跳到第 9 位去了,但是由於現在是在 8 bit,所以那個第 9 位是可以無條件捨去的,最終就會得到 8 bit 的 0。

二補數表示法的資料範圍

基本上我們可以用以下這個公式去計算所有資料型態的資料範圍。

$-2^{n-1} \leq value \leq 2^{n-1}-1$

其中正數減一是因為 0 佔走了一個 bit。

為什麼是 n-1 次方呢?因為 MSB(Most significant bit)最高位元,也就是最左邊那個位元被 0、1 表示正數的特殊符號給佔走了 1 個 bit,所以次方減 1。

各個表示法的比較表

BinaryUnsignedSign-magnitudeOne’s complementTwo’s complement
00000000
00011111
00102222
00113333
01004444
01015555
01106666
01117777
10008-0-7-8
10019-1-6-7
101010-2-5-6
101111-3-4-5
110012-4-3-4
110113-5-2-3
111014-6-1-2
111115-7-0-1

那些題目們,出來吧!

做題目囉~

來自書目 Foundations of Computer Science, Second Edition - Softcover Gilberg, Richard F.; Forouzan, Behrouz A.

  1. Store 7 in an 8-bit memory location using unsigned representation.
  2. Store 258 in a 16-bit memory location.
  3. Store +28 in an 8-bit memory location using sign-and-magnitude representation.
  4. Store -28 in an 8-bit memory location using sign-and-magnitude representation.
  5. Retrieve the integer that is stored as 01001101 in sign-and-magnitude representation.
  6. Retrieve the integer that is stored as 10100001 in sign-and-magnitude representation.
  7. Store the integer 28 in an 8-bit memory location using two’s complement representation.
  8. Store −28 in an 8-bit memory location using two’s complement representation.
  9. Retrieve the integer that is stored as 00001101 in memory in two’s complement format.
  10. Retrieve the integer that is stored as 11100110 in memory using two’s complement format.

總結

無號整數(Unsigned Integer)

  • 表示範圍: $0$ 到 $2^n - 1$ 個整數。
  • 儲存方式:直接將十進位轉換為二進位。

Sign-Magnitude Representation(原碼表示法)

  • 用最左邊的位元作為正負號標誌(0=正,1=負)。
  • 正數範例: $+28 → (00011100)₂$ 。
  • 負數範例: $-28 → (10011100)₂$ 。

缺點:

  • 存在 +0 和 -0 兩種零的表示。
  • 正負數相加會產生錯誤結果。
  • 範例: $+1 + (-1) = (00000001)₂ + (10000001)₂ = (10000010)₂ = (-2)_{10}$ (錯誤)。

Two’s Complement Representation(二補數表示法)

  • 現代計算機在用的整數表示方法,解決 Sign-Magnitude Representation 雙零(+0、-0)問題。
  • 優點:可用加法電路實現減法運算,簡化硬體設計。

計算方法:

  1. 對正數做一補數(所有位元反轉)。
  2. 對一補數完的結果加 1。

範例:

求 -5 的 8-bit 二補數:

  1. $+5 → (00000101)₂$ 。
  2. 一補數 → $(11111010)₂$ 。
  3. 加 1 → $(11111011)₂$ 。

二補數的表示法,資料範圍公式:

$-2^{n-1} \leq value \leq 2^{n-1}-1$

其中 n-1 是因為最高位元(MSB)用作正負號標記。

Reference

整數的儲存 - HackMD

二進制- 電腦儲存數值的方法

整數 (電腦科學) - 維基百科,自由的百科全書)

Day 9|電腦如何表示整數? 整數表示法 - 一補數、二補數 | iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天

計算機概論-資料儲存 | 鋼彈盪單槓

習題解答

  1. $(00000111)_2$
  2. $(0000000100000010)_2$
  3. $(00011100)_2$
  4. $(10011100)_2$
  5. +77
  6. -33
  7. $(00011100)_2$
  8. $(11100100)_2$
  9. +13
  10. -26