儲存整數的方法,在電腦裡負數是如何表示的
儲存整數的方法,在電腦裡負數是如何表示的
歡迎你點入本篇文章,會促成我想做這篇的原因,主要是因為在上計概時,突然浮現很多靈感,跟一大堆的問題(教授,為什麼要講的這麼淺白呢?我想知道更多啊啊!),為了一次解決我所有的困惑,於是製作本篇文章。
另外本篇偏向於做題篇,原理部分可能點到為止。
若文章有任何疑點及錯誤的地方歡迎提出。
上一篇文章:淺談二進位與十六進位,為什麼電腦要使用?你所不知道的二進位。
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)是把這套數字系統在電腦科學中發揚光大的一名科學家。
二補數表示法也是現在電腦採用的系統,因為它能把減法運算這個東東用加法電路來實現,簡化了硬體設計。
如何做二補數表示法?
二補數的計算方式:
- 先做 One’s complementing (一補數)(將所有位元反轉)
- 再加 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。
各個表示法的比較表
| Binary | Unsigned | Sign-magnitude | One’s complement | Two’s complement |
|---|---|---|---|---|
| 0000 | 0 | 0 | 0 | 0 |
| 0001 | 1 | 1 | 1 | 1 |
| 0010 | 2 | 2 | 2 | 2 |
| 0011 | 3 | 3 | 3 | 3 |
| 0100 | 4 | 4 | 4 | 4 |
| 0101 | 5 | 5 | 5 | 5 |
| 0110 | 6 | 6 | 6 | 6 |
| 0111 | 7 | 7 | 7 | 7 |
| 1000 | 8 | -0 | -7 | -8 |
| 1001 | 9 | -1 | -6 | -7 |
| 1010 | 10 | -2 | -5 | -6 |
| 1011 | 11 | -3 | -4 | -5 |
| 1100 | 12 | -4 | -3 | -4 |
| 1101 | 13 | -5 | -2 | -3 |
| 1110 | 14 | -6 | -1 | -2 |
| 1111 | 15 | -7 | -0 | -1 |
那些題目們,出來吧!
做題目囉~
來自書目 Foundations of Computer Science, Second Edition - Softcover Gilberg, Richard F.; Forouzan, Behrouz A.
- Store 7 in an 8-bit memory location using unsigned representation.
- Store 258 in a 16-bit memory location.
- Store +28 in an 8-bit memory location using sign-and-magnitude representation.
- Store -28 in an 8-bit memory location using sign-and-magnitude representation.
- Retrieve the integer that is stored as 01001101 in sign-and-magnitude representation.
- Retrieve the integer that is stored as 10100001 in sign-and-magnitude representation.
- Store the integer 28 in an 8-bit memory location using two’s complement representation.
- Store −28 in an 8-bit memory location using two’s complement representation.
- Retrieve the integer that is stored as 00001101 in memory in two’s complement format.
- 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。
範例:
求 -5 的 8-bit 二補數:
- $+5 → (00000101)₂$ 。
- 一補數 → $(11111010)₂$ 。
- 加 1 → $(11111011)₂$ 。
二補數的表示法,資料範圍公式:
$-2^{n-1} \leq value \leq 2^{n-1}-1$
其中 n-1 是因為最高位元(MSB)用作正負號標記。
Reference
Day 9|電腦如何表示整數? 整數表示法 - 一補數、二補數 | iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
習題解答
- $(00000111)_2$
- $(0000000100000010)_2$
- $(00011100)_2$
- $(10011100)_2$
- +77
- -33
- $(00011100)_2$
- $(11100100)_2$
- +13
- -26





