自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

一文講清楚補(bǔ)碼的本質(zhì)

開發(fā) 前端
在計(jì)算機(jī)中,所有的數(shù)字都是以二進(jìn)制的形式表示的,即均為 0 和 1 組成的各種編碼,數(shù)字的表示形式可以劃分成原碼,反碼和補(bǔ)碼。

[[431951]]

本文轉(zhuǎn)載自微信公眾號(hào)「Linux開發(fā)那些事兒」,作者LinuxThings。轉(zhuǎn)載本文請(qǐng)聯(lián)系Linux開發(fā)那些事兒公眾號(hào)。

在計(jì)算機(jī)中,所有的數(shù)字都是以二進(jìn)制的形式表示的,即均為 0 和 1 組成的各種編碼,數(shù)字的表示形式可以劃分成原碼,反碼和補(bǔ)碼

如何表示 原碼、反碼、補(bǔ)碼

如果沒有特殊說明,下面的介紹都是以 4 位二進(jìn)制為例的

原碼

為了區(qū)分正數(shù)和負(fù)數(shù),計(jì)算機(jī)中將二進(jìn)制的最高位( bit ) 規(guī)定為符號(hào)位,它等于 0 時(shí)表示正數(shù),等于 1 時(shí)表示負(fù)數(shù),剩下的所有低位( bit )用來表示數(shù)值

下面的圖片從左到右分別表示 +5 和 -5 的原碼

反碼

正數(shù)的反碼和其原碼相同,負(fù)數(shù)的反碼在原碼基礎(chǔ)上,符號(hào)位不變,數(shù)值位取反

下面的圖片從左到右分別表示 +5 和 -5 的反碼

補(bǔ)碼

正數(shù)的補(bǔ)碼和其原碼相同,負(fù)數(shù)的補(bǔ)碼在反碼基礎(chǔ)上加1

下面的圖片從左到右分別表示 +5 和 -5 的補(bǔ)碼

為什么用補(bǔ)碼

在計(jì)算機(jī)中,數(shù)字是以補(bǔ)碼的形式進(jìn)行存儲(chǔ)和參與運(yùn)算的

這看起來比較奇怪,為什么要采用補(bǔ)碼這么麻煩的方式表示數(shù)字( 特別是對(duì)于負(fù)數(shù) ),直觀一點(diǎn)兒不好嗎?

為了講明白這個(gè)問題,下面我們分別以原碼,反碼和補(bǔ)碼的形式來模擬二進(jìn)制的加法和減法運(yùn)算,以 4 位二進(jìn)制為例來說明

  • 原碼

下圖列出了 4 位二進(jìn)制所有正數(shù)和負(fù)數(shù)的二進(jìn)制表示

對(duì)于 4 位二進(jìn)制來說,最高位是符號(hào)位,也就是圖中黃色二進(jìn)制的 0 和 1 的位置

用原碼模擬 3 + 2、6 + (-2) 、(-1) + (-3) 運(yùn)算,具體的運(yùn)算過程如下:

上圖中,圓圈中的二進(jìn)制位是做加法運(yùn)算的時(shí)候向前進(jìn)位的結(jié)果,由于有效二進(jìn)制位數(shù)是 4 位,所以圓圈中的二進(jìn)制位因溢出而自動(dòng)丟棄(在計(jì)算過程中仍然用到了溢出的二進(jìn)制位,結(jié)果會(huì)丟棄溢出的二進(jìn)制)

由計(jì)算過程可知,3 + 2 = 5 是正確的,但是 6 + (-2) = 0 以及 (-1) + (-3) = 4 結(jié)果都是錯(cuò)誤的

所以,原碼雖然直觀易懂,也易于轉(zhuǎn)換,但是在運(yùn)算上,正數(shù)之間的加法是沒問題,負(fù)數(shù)之間以及正數(shù)和負(fù)數(shù)之間都存在問題,因此計(jì)算機(jī)中不能用原碼表示數(shù)字

  • 反碼

下面列出了 4 位二進(jìn)制所有正數(shù)和負(fù)數(shù)的二進(jìn)制表示,請(qǐng)看下圖

正數(shù)的反碼是其自身,負(fù)數(shù)的反碼是符號(hào)位不變,其他位取反,圖中黃色二進(jìn)制位表示符號(hào)位

用反碼模擬 3 + 2、6 + (-2) 、(-1) + (-3) 運(yùn)算,具體的運(yùn)算過程如下:

和原碼一樣,上圖中圓圈中的二進(jìn)制位由于溢出而被自動(dòng)丟棄,在反碼的運(yùn)算中,只有 3 + 2 = 5 是正確的,其他的結(jié)果都不正確

注意:(-1) + (-3) 的結(jié)果是 1010,符號(hào)位為 1,表示結(jié)果是負(fù)數(shù),根據(jù)上面負(fù)數(shù)十進(jìn)制對(duì)應(yīng)二進(jìn)制的反碼表可知,它對(duì)應(yīng)的十進(jìn)制是 -5

由反碼運(yùn)算結(jié)果來看,正數(shù)的加法結(jié)果是正確的,負(fù)數(shù)和負(fù)數(shù)以及正數(shù)和負(fù)數(shù)加法的結(jié)果是錯(cuò)誤的,所以,計(jì)算機(jī)中也不能用反碼表示數(shù)字

  • 補(bǔ)碼

說完了原碼和反碼,現(xiàn)在來看下補(bǔ)碼,下圖是正數(shù)和負(fù)數(shù)補(bǔ)碼的二進(jìn)制表示

用補(bǔ)碼模擬 3 + 2、6 + (-2) 、(-1) + (-3) 運(yùn)算,具體的運(yùn)算過程如下:

由上述計(jì)算過程可知,除去溢出的二進(jìn)制位后,3 + 2、6 + (-2) 、(-1) + (-3) 計(jì)算的結(jié)果全都正確

用原碼和反碼的表示方式,都不能解決加法運(yùn)算,但是用補(bǔ)碼表示,不管是正數(shù)之間、負(fù)數(shù)之間還是正數(shù)和負(fù)數(shù)之間的加法,都可以解決

所以,計(jì)算機(jī)選擇用補(bǔ)碼來表示數(shù)字以及用補(bǔ)碼進(jìn)行運(yùn)算

補(bǔ)碼的好處

  • 簡化減法計(jì)算

補(bǔ)碼在加法或減法處理中,不需因?yàn)閿?shù)字的正負(fù)而使用不同的計(jì)算方式。只要一種加法電路就可以處理各種有符號(hào)數(shù)和無符號(hào)數(shù)加法

而且減法可以用一個(gè)數(shù)加上另一個(gè)數(shù)的補(bǔ)碼來表示,因此只要有加法電路及補(bǔ)碼電路即可完成各種有符號(hào)數(shù)和無符號(hào)數(shù)加法及減法,在電路設(shè)計(jì)上相當(dāng)方便

  • 統(tǒng)一表示數(shù)字 0

另外,根據(jù)上一小節(jié)中,+0 和 -0 的補(bǔ)碼都是 0000,對(duì)應(yīng)的十進(jìn)制是 0

也就是說 0 的補(bǔ)碼就只有一種表示方式,在計(jì)算機(jī)中也就有唯一的表示,這和反碼不同(在反碼中,0 有二種二進(jìn)制表示方式),因此在判斷數(shù)字是否為 0 時(shí),只要比較一次即可

由于 +0 和 -0 的補(bǔ)碼只有一種表示方式,即 0000,但是原碼和反碼都有兩種表示方式,所以補(bǔ)碼會(huì)多出一種二進(jìn)制表示方式 1000( 以 4 位二進(jìn)制為例 ),對(duì)應(yīng)十進(jìn)制數(shù) -8

補(bǔ)碼是怎么來的

前面講到 負(fù)數(shù)的補(bǔ)碼是其反碼加 1 , 為什么要這么計(jì)算呢, 這么計(jì)算就是有效嗎 ?

在十進(jìn)制中,一個(gè)負(fù)數(shù)可以通過 0 減去一個(gè)正數(shù)得到,同樣的,二進(jìn)制中也可以

比如:-3 可以表示成 0 - 3,也可以表示成下面的二進(jìn)制減法計(jì)算

因?yàn)?0 ( 0000 ) 小于 3 ( 0011 ),根據(jù)算術(shù)運(yùn)算規(guī)則,當(dāng)被減數(shù)的位小于減數(shù)時(shí),需向前一位借 1,

0000 向前一位借 1 后變成了 1 0000,于是,上面的減法計(jì)算就變成了

我們知道, 1 0000 可以表示成 1111 與 1 的和, 也即 1 0000 = 1111 + 1, 于是,計(jì)算就變成了

根據(jù)上面的計(jì)算,0 ( 0000) 減 3(0011) 的結(jié)果是 1101, 而 1101 剛好是 -3 的補(bǔ)碼

其實(shí),上面的計(jì)算過程就相當(dāng)于先求反碼然后加 1 , 請(qǐng)看下圖:

用 1111 減去 3 的源碼 0011,結(jié)果是 -3 的反碼 1100,然后再加 1 ,得到 -3 的補(bǔ)碼 1101

再看看前面介紹的,負(fù)數(shù)的補(bǔ)碼等于其反碼加 1,是不是有點(diǎn)兒似曾相識(shí)呢,是的,負(fù)數(shù)的反碼就是這么來的,它并不是一個(gè)毫無根據(jù)的定義,而是通過上面的計(jì)算一步一步得出來的,只不過補(bǔ)碼的計(jì)算方式剛好是其反碼加 1 而已

為什么補(bǔ)碼適合正數(shù)的加法

我們還是以 4 位二進(jìn)制為例來進(jìn)行說明

假如有兩個(gè)正數(shù) A 和 B,現(xiàn)在要證明 A 減 B 的結(jié)果等于 A 加上 B 的補(bǔ)碼

減去一個(gè)數(shù)等于加上一個(gè)負(fù)數(shù),所以 A - B = A + ( 0 - B )

由上一小節(jié)可知, ( 0 - B ) 等價(jià)于 ( 1111 - B ) + 1

所以,A 加 B 的補(bǔ)碼就等于 A + ( 1111 - B ) + 1,假如結(jié)果為 R ,則有 R = A + ( 1111 - B ) + 1

A + ( 1111 - B ) + 1 可以寫成 A - B + ( 1111 + 1 )

A - B + ( 1111 + 1 ) 又可以寫成 A - B + 1 0000 ( 1111 + 1 = 1 0000 )

我們是以 4 位二進(jìn)制為例的, 1 0000 已經(jīng)超過 4 位了,所以加 1 0000 時(shí),最高位會(huì)因溢出而被丟棄

其實(shí)這時(shí) 1 0000 就相當(dāng)于 0000 了(最高位溢出,需要丟棄)

所以,上面的計(jì)算

  1. R = A + ( 1111 - B ) + 1 
  2.   = A - B + ( 1111 + 1 )  
  3.   = A - B + 1 0000 
  4.   = A - B +   0000 
  5.   = A - B 

這樣就證明了 A 減 B 等于 A 加上 B 的補(bǔ)碼

小結(jié)

本文介紹了原碼、反碼以及補(bǔ)碼,重點(diǎn)闡述了補(bǔ)碼的由來以及證明了補(bǔ)碼計(jì)算正數(shù)加法的可行性。

 

責(zé)任編輯:武曉燕 來源: Linux開發(fā)那些事兒
相關(guān)推薦

2018-05-21 07:08:18

行為驅(qū)動(dòng)開發(fā)BDD編碼

2024-02-23 10:41:29

2020-10-26 09:18:50

RedisCluste

2017-12-17 20:17:23

NoSQLSQL數(shù)據(jù)

2018-08-13 09:20:21

NoSQLSQL數(shù)據(jù)

2020-07-29 09:21:34

Docker集群部署隔離環(huán)境

2021-07-05 22:22:24

協(xié)議MQTT

2019-06-20 17:49:51

RPCHTTP協(xié)議

2020-04-01 17:26:57

MySQL事務(wù)隔離級(jí)別數(shù)據(jù)庫

2019-07-07 08:18:10

MySQL索引數(shù)據(jù)庫

2022-01-05 09:27:24

讀擴(kuò)散寫擴(kuò)散feed

2021-04-21 10:00:08

MySQL索引數(shù)據(jù)庫

2024-04-01 10:09:23

AutowiredSpring容器

2024-01-05 07:55:39

Linux虛擬內(nèi)存

2020-03-26 09:18:54

高薪本質(zhì)因素

2021-07-07 10:28:09

分布式架構(gòu)系統(tǒng)

2019-11-25 08:25:47

ZooKeeper分布式系統(tǒng)負(fù)載均衡

2025-03-03 08:40:00

JavaScriptthis開發(fā)

2021-10-19 10:10:51

MySQL事務(wù)隔離級(jí)別數(shù)據(jù)庫

2019-01-31 09:20:36

架構(gòu)容錯(cuò)架構(gòu)分布式容錯(cuò)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)