斯坦福編程範式第二課筆記-數據類型在內存中的表示

內存的最小單位是字節,一個字節等於8位(bit),每一位要麼是0要麼是1,也就是用二進制來表示。spa

一個字節在內存中的表示爲:3d

無符號整數的表示

無符號二進制轉成十進制公式:code

  • w:二進制位的長度。
  • i:二進制位從右往左開始的下標,從0開始計數。
  • w-1:因爲i是從0開始計數,因此最後一個下標就是w-1。
  • x(i):第i位的值,要麼是0要麼是1。
  • 2^i:2的第i次冪。

例如:
無符號二進制數10010 按照公式展開就是:blog

若是把這個數用1個字節在計算機中存儲,內存中就表示爲:內存

不足8位,左邊補0。rem

1個字節的無符號正式能表示2^8 = 256個不一樣的數。能表示最大的數是8個二進位全是1的數等於255,也就是求一個公比爲2首項是1等比數列前8項和。二進制位求和公式爲(2^n) - 1。總結下來一個n位的二進制數能表示最大的數是(2^n) - 1,可以表示2^n個不一樣的數,之因此是2^n個不一樣的數,是由於能夠表示0~(2^n) - 1,從0開始的因此還須要+1個長度。it

Char在內存中的表示

Char類型是用來存儲單個字符,在內存中佔用1個字節的大小,它使用8個bit來表示256個字符。
Char類型實際存儲的是字符的 ASCII碼,因爲 ASCII碼是整數。因此Char最終在內存中是一個8bit的整型。

好比字符AASCII碼是65,65 = 2^0 + 2^6,因此在內存中的表示爲:
class

char ch = 'A';
printf("%d", ch); // output is 65

Short在內存中的表示

Short 表示的是短整型,通常佔用2個字節的內存大小。

它的取值範圍是(-2)^15~(2^15)-1包含0。最大值這裏是(2^15)-1,是由於short有符號位,須要用最高位(用從左到右第一位)來表示符號,0表示正數,1表示負數。 最大值的二進制表示爲0111111111111111(16個二進制位),十進制就是(2^15)-1。 之因此是(2^15)-1,也是以前說的求和公式((2^n)-1基礎

實現加減法

二進制加減法和十進制同樣,把對應 相加,大於1就向前進位。例如 0111 + 1 = 1000

若是想要把7和-7相加使結果等於0。按照在計算機中使用二進制的最高位來當作符號位的,0表示正數,1表示負數。那麼7表示爲0000111,-7就表示爲1000111 。0000111 + 1000111 按照二進制先前的加法法則得出來是1001110,結果不是咱們想要的0。變量

怎麼才能讓2個二進制數相加獲得0呢?

想要獲得0,就須要利用進位,好比在11111111(8個1)的基礎上加1就能夠獲得100000000(一共9位,左邊第一位是1,後面8個0) ,舍掉最左邊的那個1就獲得了8個0最終結果就等於0。把原碼按位取反而後與原碼相加就能夠獲得全1的二進制數。好比0000111按位取反就是1111000,他們倆相加獲得11111111。 再把它加1就獲得最後的結果0。整個過程須要3步,咱們把最後兩步合併成一個步驟,也就是把按位取反和加1合併到一塊兒,其實就是把原碼的反碼加1。如1111000加1獲得1111001。最後這兩步合在一塊兒叫作取原碼的補碼。最後獲得的1111001就叫作0000111的補碼。

  • 正整數的補碼是其自己。
  • 負整數的補碼是把它對應的正整數二進制碼按位取反,也就作原碼的反碼而後再加1。

好比正整數7的二進制碼是0000111,它的補碼仍是它自己。再好比-7對應的正整數二進制碼是0000111,它的反碼就是1111000(把原碼按位取反)。而後再加1就獲得11110011111001就是-7的補碼。咱們再次把11110010000111按照二進制加法法則相加恰好獲得0。這裏須要注意的是,這裏左邊會產生一個溢出位,這個溢出位是去掉不要的,獲得結果就是0。

-1的補碼全是1,由於它加上1以後就變成了0。

計算機系統都是用補碼來表示二進制碼,這樣的好處之一就是可讓加減法運算統一處理。

位模式拷貝

當把 char類型的變量賦值給 short類型的變量時,會把 char的8個bit放在 short的低八位(從右往左第一個字節)上。

例如:

char ch = 'A'; // 'A' ASCII:65 內存表示爲 01000001
short s = ch; // 內存表示爲 00000000 | 01000001

一個特殊的狀況就是當把一個short-1賦值給一個int變量的時候,並不會獲得00000000 | 00000000 | 11111111 | 11111111,由於若是這樣的話表示的值就不是-1了。因此正確的作法就是把全部的1所有拷貝給int
例如:

short s = -1; // 內存表示爲 11111111 | 11111111
int i = s; // 內存表示爲 11111111 | 11111111 | 11111111 | 11111111

相反若是把short類型的變量賦值給char類型的變量時,會把short的低八位(從右往左第一個字節)放在char僅有的一個字節上。會把多的字節自動剔除。
例如:

short s = 65; // 內存表示爲 00000001 | 01000001
char ch = s; // 內存表示爲 01000001

浮點數的表示

咱們已經知道無符號二進制轉成十進制公式爲:

這裏的i是從0開始的也就是從右邊的第一位是2^0,若是咱們從一個負整數開始的話,就會存在負整數次冪,那麼也就會出現小數部分了。
例若有一個16位的二進制數000000011 | 11000000 用它的前八位來表示整數部分,後八位來表示小數部分,就也能夠這樣表示000000011.11000000。這樣後八位也就再也不是整數次冪了,而是從左到右每一位分別是2^(-1)~2^(-8)。這個數就能夠表示成:

這是其中一種浮點數表示方法,這種方法表示的浮點數會出現精度不夠,表示的數值區間比較小,因此計算機實際並無用該方法來表示浮點數。

下面這種方法就是計算機內部真實表示浮點數的方法。

咱們先來看下十進制的科學計數法,用科學計數法表示123.45的話就是1.2345 * 10^2。其中1.2345 爲尾數,10爲基數,2爲指數。計算機在表示浮點數的時候,也借用了十進制的科學計數法的思想,只不過基數爲2了。

例如1000.01 能夠表示成1.00001 * 2^3,幾回冪,小數點就向右移動幾位。

32位float來舉例,首位是符號位S,緊跟後面8位是指數位E,最後23位稱爲尾數位M

計算公式:

  • S:符號位
S爲0時恰好是正數,爲1時是負數。
  • M:尾數部分
它的取值範圍是 1≤M<2,取值方式是從左到右每一位分別表示的是 2^-1~2^-23,值就是而後對各個位的表示值求和,這裏跟先前浮點數表示的辦法一致,都是從負整數次冪開始。因爲尾數的整數部分始終都是 1,因此這個 1能夠被省略,這樣就能夠多出一位來提高精度。
  • E:指數部分
減去127是由於偏移量是127。

例如0 | 10000010 | 11110000000000000000000的每一部分別是:

  • S:0
表示整數。
  • M:11110000000000000000000
這裏須要再加1,由於爲了提高小數精度省略了1,因此要加回來。因此完整的尾數部分應該是 1.1111(省略了後面的0)。 2^0 + 2^-1 + 2^-2 + 2^-3 + 2^-4 = 1.9375
  • E:10000010
2^7 + 2^1 = 130

分別帶入公式得:

二進制形式:

十進制形式:

詳細過程:
1 * 1.1111 * 2^(130-127) => 1 * 1.1111 * 2^3 => 1 * 1111.1(幾回冪,小數點就向右移動幾位) => 1 * (2^3 + 2^2 + 2^1 + 2^0 + 2^-1) => 1 * (8 + 4 + 2 + 1 + 0.5) => 15.5

浮點數與整數相互賦值

當咱們在把浮點數與整數相互賦值的時候,並不會直接拷貝bit位,而是從新計算出在新的類型中的位模式。
例如:

int i = 5; // 內存表示 00000000 | 00000000 | 00000000 | 00000101
// 從新計算5在float中的表示方式
float f = i; // 內存表示 0 | 00000000 | 00000000000000000000101
printf("%f", f) // output is 5.0

來一點更刺激的!!!

// 2^30
int i = 1073741824; // 內存表示 01000000 | 00000000 | 00000000 | 00000000
// 這裏就不會從新計算在float中的表示方式了,而是直接把bit位拷貝過去。用float的解析方式去解析int的那塊內存。
float f = *(float *)&i; // 內存表示 0 | 10000000 |00000000000000000000000

// 1 * 2^(128-127) * 1 = 2
printf("%f", f) // output is 2.0

這裏就不會從新計算1073741824在float中的表示方式了,而是直接把intbit位拷貝過去。用float的解析方式去解析int的那塊內存

相關文章
相關標籤/搜索