有符號(hào)數(shù)的主要用途是表示負(fù)數(shù)代虾。
在某些語言里數(shù)值類型可標(biāo)志為有符號(hào)或無符號(hào)进肯,如 c 語言的整數(shù)類型 int
默認(rèn)是有符號(hào),加上 unsigned
就是無符號(hào)棉磨。
有符號(hào)表達(dá)方式里將最高位 MSB 用作符號(hào)位江掩,因此對(duì)于位數(shù)為32的有符號(hào)數(shù)能表示的非負(fù)整數(shù)范圍為
比無符號(hào)中的
少了大概一半:2147483647 * 2 + 1 = 4294967295。
目前主導(dǎo)的表達(dá)方式為更先進(jìn)的 two's complement乘瓤,只有很老的系統(tǒng)還在使用 ones' complement 或者 sign-magnitude 环形,以下會(huì)對(duì)它們進(jìn)行描述和比較。
sign-magnitude
sign-magnitude 正如其名把位數(shù)分為 sign 和 magnitude 部分衙傀。
最高位作為 sign 表示符號(hào)抬吟,其余位作為 magnitude 表示數(shù)值。
這種表達(dá)方式對(duì)人來說最容易理解统抬,例如
binary | sign-magnitude interpretation |
---|---|
0000 0000 | +0 |
... | ... |
0111 1111 | 127 |
1000 0000 | -0 |
... | ... |
1111 1111 | -127 |
但這種表達(dá)方式有2個(gè)缺點(diǎn)
- 對(duì)于0來說有2種表達(dá)方式:+0和-0
- cpu需要額外的減法部件進(jìn)行減法運(yùn)算
ones' complement
ones' complement 表達(dá)方式中負(fù)數(shù)的表達(dá)通過對(duì)相應(yīng)正數(shù)進(jìn)行取反位操作(包括符號(hào)位)取得火本,可對(duì)比以下 127 與 -127 的表達(dá)方式。
反過來聪建,對(duì)負(fù)數(shù)的表達(dá)取反可取得相應(yīng)正數(shù)的表達(dá)钙畔。
binary | ones' complement interpretation |
---|---|
0000 0000 | +0 |
... | ... |
0111 1111 | 127 |
1000 0000 | -127 |
... | ... |
1111 1111 | -0 |
它不像 sign-magnitude 需要額外減法部件來進(jìn)行減法運(yùn)算,它的減法實(shí)際上也是加法金麸,只是遇到超過最高位進(jìn)位時(shí)需要進(jìn)行 end-around carry 將進(jìn)位的1加回上去才能得到正確的結(jié)果擎析,例如
?1 1111 1110
與 +2 0000 0010
相加
binary decimal
11111110 ?1
+ 00000010 +2
............ …
1 00000000 0 ← 不是正確的結(jié)果
1 +1 ← 加上進(jìn)位
............ …
00000001 1 ← 正確的結(jié)果
有趣的一點(diǎn)是 sign-magnitude 和 ones' complement 的負(fù)數(shù)表達(dá)形式可以通過對(duì)除符號(hào)位外的位取反相互獲得。
例如 -127 在 sign-magnitude 和 ones' complement 中分別是 1111 1111
和 1000 0000
钱骂。
它的可表達(dá)范圍與 sign-magnitude 相同叔锐。
但它還是存在 sign-magnitude 中另一個(gè)缺點(diǎn)
- 對(duì)于0來說有2種表達(dá)方式:+0和-0
two's complement
對(duì)two's complement 表達(dá)方式來說挪鹏,以上2種表達(dá)方式的缺點(diǎn)都不復(fù)存在。
負(fù)數(shù)表達(dá)的獲得步驟是
- 對(duì)相應(yīng)正數(shù)(包括符號(hào)位)取反。
- 加一
binary | two's complement interpretation |
---|---|
0000 0000 | 0 |
... | ... |
0111 1111 | 127 |
1000 0000 | -128 |
1000 0001 | -127 |
... | ... |
1111 1111 | -1 |
對(duì)于0只有一種表達(dá)
two's complement 的設(shè)計(jì)讓它對(duì)于0只有一種表達(dá)方式 0000 0000
页徐,因此比 sign-magnitude 和 ones' complement 都多出一個(gè) binary code愈案,能多表示一個(gè)負(fù)數(shù)。
因此 two's complement 的表達(dá)范圍從
加法和減法
與 ones' complement 一樣返顺,它不需要額外的減法部件進(jìn)行減法運(yùn)算禀苦,更優(yōu)勝的是它不需要 end-around carry 就可以獲得正確結(jié)果蔓肯。
如 -1 1111 1111
與 +2 0000 0010
相加
binary decimal
11111111 ?1
+ 00000010 +2
............ …
1 00000001 1 ← 最高位進(jìn)位直接舍棄
............ …
00000001 1 ← 正確的結(jié)果
名字由來
至于為什么叫作 two's complement 呢,因?yàn)楂@得負(fù)數(shù)的表達(dá)除了以上提到的方法外振乏,還有另一種能體現(xiàn)這個(gè)名字的方法蔗包。
假設(shè)位數(shù)為 n 的正數(shù) x,那負(fù)數(shù) -x 的表達(dá)就是 x 的 2的n次冪 的補(bǔ)集
例如 n=8, 正數(shù) 7
0000 0111
慧邮,那負(fù)數(shù) -7 的表達(dá)可通過以下獲得也就是 -7 在 two's complement 中的表達(dá)為
1111 1001
调限。