整數在記憶體中是如何儲存的,為什麼它堪稱天才般的設計

2022-08-14 12:51:13 字數 4338 閱讀 9324

正文:

加法和減法是計算機中最基本的運算,計算機時時刻刻都離不開它們,所以它們得由硬體直接支援。為了提高加減法的運算效率,硬體電路需要設計地足夠精簡。

對於有符號數,記憶體要區分符號位和數值位,對於人腦來說,很容易辨別,但是對於計算機而言,就要設計專門的電路,這無疑增加了硬體的複雜性,增加了計算的時間。要是能把符號位和數值位等同起來,讓它們一起參與運算,不再加以區分,這樣硬體電路就變得簡單了起來。

另外,加法和減法也可以合併為一種運算,就是加法運算,因為減去乙個數相當於加上這個數的相反數,例如:5 - 3等價於 5 + (-3),10 - (-9)等價於10+9.

相反數是指數值相同,符號不同的兩個數,例如,10和-10就是一堆相反數,-98和98也是一對相反數。如果能夠實現上面的兩個目標,那麼只要設計一種簡單的、不用區分符號位和數值位的加法電路,就能同時實現加法和減法運算,並且非常高效。實際上,這兩個目標都已經實現了,真正的計算機硬體電路就是如此簡單。

然而,簡化硬體電路是有代價的,這個代價就是有符號數在儲存和讀取時都要進行轉化。那麼,這個轉換過程究竟是怎樣的呢?接下來我們就詳細地講解一下。

首先,請記住如下幾個概念。

(1)原碼

將乙個整數轉換成二進位制形式,就是其原碼。例如short a = 6;a的原碼就是0000 0000 0000 0110;更改a的值a = -18,此時a的原碼就是1000 0000 0001 0010。

通俗的理解,原碼就是乙個整數本來的二進位制形式

(2)反碼

談到反碼,需要將正數和負數區別對待,因為它們的反碼不一樣。

對於正數,它的反碼就是其原碼(原碼和反碼相同);負數的反碼就是將原碼中除符號位以外的所有位(數值位)取反,也就是0變成1,1變成0.。例如short a = 6,a的原碼和反碼都是0000 0000 0000 0110;更改a的值a = -18,此時a的反碼是 1111 1111 1110 1101.

(3)補碼

正數和負數的補碼也不一樣,也要區別對待。

對於正數,它的補碼就是其原碼(原碼、反碼、補碼都相同);負數的補碼是其反碼加 1。例如short a = 6;,a 的原碼、反碼、補碼都是0000 0000 0000 0110;更改 a 的值a = -18;,此時 a 的補碼是1111 1111 1110 1110

可以認為,補碼是在反碼的基礎上打了乙個補丁,進行了一下修正,所以叫「補碼」。

原碼、反碼、補碼的概念只對負數有實際意義,對於正數,它們都一樣。

最後我們總結一下 6 和 -18 從原碼到補碼的轉換過程:

在計算機記憶體中,整數一律採用補碼的形式來儲存。這意味著,當讀取整數時還要採用逆向的轉換,也就是將補碼轉換為原碼。將補碼轉換為原碼也很簡單:先減去 1,再將數值位取反即可。

補碼到底是如何簡化電路的

假設 6 和 18 都是 short 型別的,現在我們要計算 6 - 18 的結果,根據運算規則,它等價於 6 + (-18)。

如果採用原碼計算,那麼運算過程為:

6 - 18 = 6 + (-18)

= [0000 0000 0000 0110]原 + [1000 0000 0001 0010]原

= [1000 0000 0001 1000]原

= -24

直接用原碼表示整數,讓符號位也參與運算,對於類似上面的減法來說,結果顯然是不正確的。

於是人們開始繼續探索,不斷試錯,後來設計出了反碼。下面就演示了反碼運算的過程:

6 - 18 = 6 + (-18)

= [0000 0000 0000 0110]反 + [1111 1111 1110 1101]反

= [1111 1111 1111 0011]反

= [1000 0000 0000 1100]原

= -12

這樣一來,計算結果就正確了。

然而,這樣還不算萬事大吉,我們不妨將減數和被減數交換一下位置,也就是計算 18 - 6 的結果:

18 - 6 = 18 + (-6)

= [0000 0000 0001 0010]反 + [1111 1111 1111 1001]反

= [10000 0000 0000 1011]反

= [0000 0000 0000 1011]反

= [0000 0000 0000 1011]原

= 11 

按照反碼計算的結果是 11,而真實的結果應該是 12 才對,它們相差了 1。

加粗的1是加法運算過程中的進製,它溢位了,記憶體容納不了了,所以直接截掉。

6 - 18 的結果正確,18 - 6 的結果就不正確,相差 1。按照反碼來計算,是不是小數減去大數正確,大數減去小數就不對了,始終相差 1 呢?我們不妨再看兩個例子,分別是 5 - 13 和 13 - 5。

5 - 13 的運算過程為:

5 - 13 = 5 + (-13)

= [0000 0000 0000 0101]原 + [1000 0000 0000 1101]原

=  [0000 0000 0000 0101]反 + [1111 1111 1111 0010]反

= [1111 1111 1111 0111]反

= [1000 0000 0000 1000]原

= -8

13 - 5 的運算過程為:

13 - 5 = 13 + (-5)

= [0000 0000 0000 1101]原 + [1000 0000 0000 0101]原

= [0000 0000 0000 1101]反 + [1111 1111 1111 1010]反

= [10000 0000 0000 0111]反

= [0000 0000 0000 0111]反

= [0000 0000 0000 0111]原

= 7這足以證明,剛才的猜想是正確的:小數減去大數不會有問題,而大數減去小數的就不對了,結果始終相差 1。

相差的這個 1 要進行糾正,但是又不能影響小數減去大數,怎麼辦呢?於是人們又絞盡腦汁設計出了補碼,給反碼打了乙個「補丁」,終於把相差的 1 給糾正過來了。

下面演示了按照補碼計算的過程:

6 - 18 = 6 + (-18)

= [0000 0000 0000 0110]補 + [1111 1111 1110 1110]補

= [1111 1111 1111 0100]補

= [1111 1111 1111 0011]反

= [1000 0000 0000 1100]原

= -12

18 - 6 = 18 + (-6)

= [0000 0000 0001 0010]補 + [1111 1111 1111 1010]補

= [10000 0000 0000 1100]補

= [0000 0000 0000 1100]補

= [0000 0000 0000 1100]反

= [0000 0000 0000 1100]原

= 12

5 - 13 = 5 + (-13)

=  [0000 0000 0000 0101]補 + [1111 1111 1111 0011]補

= [1111 1111 1111 1000]補

= [1000 1111 1111 0111]反

= [1000 0000 0000 1000]原

= -8

13 - 5 = 13 + (-5)

= [0000 0000 0000 1101]補 + [1111 1111 1111 1011]補

= [10000 0000 0000 1000]補

= [0000 0000 0000 1000]補

= [0000 0000 0000 1000]反

= [0000 0000 0000 1000]原

= 8你看,採用補碼的形式正好把相差的 1 糾正過來,也沒有影響到小數減去大數,這個「補丁」真是巧妙。

小數減去大數,結果為負數,之前(負數從反碼轉換為補碼要加 1)加上的 1,後來(負數從補碼轉換為反碼要減 1)還要減去,正好抵消掉,所以不會受影響。

而大數減去小數,結果為正數,之前(負數從反碼轉換為補碼要加 1)加上的 1,後來(正數的補碼和反碼相同,從補碼轉換為反碼不用減 1)就沒有再減去,不能抵消掉,這就相當於給計算結果多加了乙個 1。

補碼這種天才般的設計,一舉達成了本文開頭提到的兩個目標,簡化了硬體電路。

128在記憶體中如何儲存

在c語言的學習中,我們都知道型別分為有符號和無符號,無符號型別能夠定義的最大值是有符號所定義最大值的二倍加一,因為二者中都有乙個0的存在所影響的。那麼負的最小值是怎麼儲存的呢,這裡就拿char型別來說明吧,無符號char的範圍是0 255,有符號的char範圍是 128 127。規定是這樣,但是在記...

整數,浮點數在記憶體中的儲存

整數 符號數 計算機中的符號數有三種表示方法,即原碼,反碼和補碼。三種表示方法均有符號位和數值位兩部分,符號位都是用0表示 正 用1表示 負 而數值位表示方法各不相同。原碼 直接將二進位制按照正負數的形式翻譯成二進位制就可以。反碼 符號位不變,其他位按位取反即可得到。補碼 反碼加一得到補碼。在計算機...

整型資料在記憶體中如何儲存

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!以下討論,針對32位的計算機系統。問 int型資料佔幾個位元組?答 4位元組。地球上這個群體的人都知道。再問 這4個位元組,即32個二進位制位,又是何儲存?這就進入計算機的 底層 了。這個事情,學習程式設計的童鞋,可以懂。儲存的方式,和我們拍腦袋想...