1. 程式人生 > 其它 >CMU-15213(計算機作業系統總結) - 第一章

CMU-15213(計算機作業系統總結) - 第一章

技術標籤:CMU-15213(計算機作業系統總結系列)補碼c++c語言

CMU-15213(計算機作業系統總結) - 第一章

事實1: Int(整數型別)不是整數, Float(浮點數)也不是自然數

例子:x^2\geq 0?

x是Int型別:

  • 40000*40000\rightarrow 1600000000
  • 50000*50000\rightarrow ??

我們可以通過程式碼來驗證一下

#include <stdio.h>

int main()
{
    int x;
    x = 40000;
    printf("%d * %d -> %d\n", x, x, x*x);
    x = 50000;
    printf("%d * %d -> %d\n", x, x, x*x);
    return 0;
}
40000 * 40000 -> 1600000000                                                          
50000 * 50000 -> -1794967296

我們不難發現打印出的結果是50000*50000\rightarrow -1794967296,不僅算錯,而且還是一個負數,這是為什麼呢?這就需要介紹Int型別在計算機系統裡是如何表示的了。

討論

在多數電腦中,Int被定義為4 bytes也就是32bits

型別32bits環境下64bits環境下
char1 byte1 byte
short2 bytes2 bytes
int4 bytes4 bytes
long4 bytes8 bytes

那麼用32bits我們可以怎麼來表達一個整數呢?這裡要介紹的一種是絕大多數系統採用的表達整數的方式

二進位制補碼(two's complement):

公式:

B2T(X)=-{ x_{w-1} * {2^{w-1}} + \sum_{i=0}^{w-2}x_i*2^i}

例子:

其實舉個簡單的例子就是

10=01010=2^{-4}+2^{3}+2^{2}+2^{1}+2^{0}

第4位第3位第2位第1位第0位
2^{-4}2^{3}2^{2}2^{1}2^{0}
-168421
01010

在瞭解了二進位制補碼之後,我們就可以算出在int型別有32bits並且使用二進位制補碼的情況下,int型別最大可以表示多少呢?

32bits二進位制十進位制
INT_MAX(整數最大值)01111111 11111111 11111111 111111112,147,483,647
INT_MIN(整數最小值)10000000 00000000 00000000 00000000-2,147,483,648

我們可以很簡單的證明正確性,既然第一位bit代表2^{-31},其他bits都是代表正數,所以如果其他位置上有為1的bit那麼這個值必然比INT_MIN

要大,所以INT_MINint型別可以表示的最小值。同理也可以說明INT_MAX是int可以表示的最大值。

知識點:

INT_MIN的絕對值是INT_MAX+1

回到問題本身

瞭解了int型別可以表示的最大值,我們不難發現

50000*50000\rightarrow 2,500,000,000>2,147,483,647

50000乘50000導致了儲存結果的int型別變數溢位。但是為什麼結果是-1794967296這麼一個奇怪的負數呢?

十進位制-179496729650000
二進位制10010101 00000010 11111001 0000000000000000 00000000 11000011 01010000
十進位制50000*50000=2500000000
二進位制

00000000 00000000 11000011 01010000

×

00000000 00000000 11000011 01010000
=

0 10010101 00000010 11111001 00000000

我們可以看到32bits的無法表示2,500,000,000這個結果,導致2^{32}被忽略,所以正確答案應該是-1794967296+2^{32}=2500000000

事實2:

你需要了解組合語言,雖然我們大概率不會自己寫組合語言,但是我們需要了解他是如何構成的。

事實3: RAM(Random Access Memory)是個Unphysical Abstraction

  • Memory referencing bugs especially pernicious
    • Effects are distant in both time and space
  • Memory is not unbounded
    • It must be allocated and managed
    • Many applications are memory dominated
  • Memory performance is not uniform
    • Cache and virtual memory effects can greatly affect program performance
    • Adapting program to characteristics of memory system can lead to major speed improvements

比如c和c++沒有任何記憶體保護機制,所以他會出現

  • 陣列越界
  • 無效指標
  • 錯誤的malloc()和free()

這種錯誤往往很難debug,比如陣列很有可能在大多數情況都不會越界,但是因為程式設計師沒有考慮到一些情況而導致陣列越界,導致程式崩潰,無效指標和錯誤的malloc()和free()也會導致類似的錯誤。