基礎數據在內存中的存儲-C語言

在計算機中所有的數據存儲都是二進制

1  十進制與二進制的轉換

1.1 二進制轉十進制 

         假如數據10.101,對應各個位數 爲  ab.cde ,則轉換爲十進制的數據
         a*2的1次方+ b*2的0次方+c*2的-1次方+d*2的-2次方 +e*2的-3次方 
         1*2(1)+0*2(0) + 1*2(-1)+0*2(-2)+1*2(-3)

1.2 十進制轉二進制 

        整數:除2取餘,逆序排列,用2整除十進制數,得到 商 和餘數,然後在用2整除商,再得到商和餘數,循環進行,直到商爲0 ,最後把餘數逆序排列。
        以下以10爲例
       10(十進制)  
                商    餘數
       10/2  5     0
       5/2    2     1
       2/2    1     0 
       1/2    0     1
       1010(二進制)
       小數 :乘2取整,順序排列,用2乘十進制小數,得到積,把整數部分取出,再用2乘餘下的小數部分,又得到一個積,再把積的整數部分取出,循環進行,直到積中的小數部分爲零,或者達到要求的精度,最後把整數部分順序排列
       例1 
       0.125(十進制)
--------------------------------
                     積       整數部分
       0.125*2  0.25     0
       0.25*2    0.5       0
       0.5*2      1.0       1  
        0.001(二進制)

       例2

  0.11(十進制)
--------------------------------
0.11 *2   0.22   0
0.22*2    0.44   0
0.44*2    0.88   0
0.88*2    1.76   1
0.76*2    1.52   1
        0.52*2    1.04   1
        0.04*2    0.08   0
        。。。。。。。
       無窮盡,如果要用32個二進制位存儲這個數據,只能捨棄低位,保留高位。
       得到二進制數0.0001110...

2、char  int  short  long 存儲  

      對於這幾種類型的變量,都是用來存儲 整數數據,只不過因爲所佔內存大小不同而表示的數據的範圍不同。
      看代碼的時候要分兩個層面:
      (1)代碼層面,代碼根據語法是如何寫的。
      (2)計算機層面,編譯器是如何翻譯的。
       比如 char 類型,有的人說它是字符類型,存儲的是字符,這個理解是不全面的。
       char  a = 1;  char 佔1個字節可以表示數據 0-255,當然可以存儲整數數據1.
       char a = '1';   單引號括起來的是字符數據,這是我們人類理解的概念,人在寫代碼的時候是能看明白的,但是計算機不明白,這就要用編譯器來給它翻譯過來,最終計算機存儲的是 字符'1' 的ascii碼,其實這個ascii碼也是個整數數據。
     
        最終 整數數據 都轉化成二進制存儲到了計算機中,並且用的是補碼。

2.1 爲什麼要補碼 

      如果只有 大於0的數和加法,那麼就不需要補碼這個東西。

    (1)計算機硬件支持加法 ,如果要支持減法要額外硬件電路,但是減法可以用加法加上一個負數來代替,所以按照這個思路就省了這部分硬件。
    (2)模的概念
             a 如果一個數據的範圍是 0-9,那麼就是有10個有效狀態,10就是這個數據的模
             b 在模的概念下    假定模 是M  ,   X+Y = M ,我們說X與Y 互補。
             c  兩個互補的數在模的概念下  可以互爲 負數 :比如
                 時鐘 一圈的數字  是 0-11,它的模是12,  那麼如果我現在在0初去轉錶針,想轉到3的位置,則
                 我可以是正轉  3下,也可以反轉9下,所以在模爲12的這個系統下,可以用3代表-9。
    (3)對於一個字節的char 變量來說 ,佔8bit ,可以表示256個狀態,表示非負數  0-255,模爲256.
             當數據爲 1111 1111 時,再+1 則得到的數據 爲 1 0000 0000,最終會捨棄最高位的1,保留0000 0000,這樣一圈又迴歸到0了。
             如果要表示負數,則一分未二,128個負數,128個非負數,最高位爲符號位,當爲1時,表示負數,0時表示非負數。

2.2  如何求補碼 

     (1)非負數補碼 =  原碼
     (2)負數補碼 = 反碼+1,計算規則是,符號位不變,其他位按位取反,最後這個數據+1
      比如  -1 如下算法
      0000 0001   正1
      1000 0001   如果是負數,則符號位爲1
      1111 1110   符號位不變,其他位按位取反
      1111 1111   再+1 得到-1的補碼。
      如下計算:
      1-1 --》 1+(-1) --》0000 0001 + 1111 1111 = 1 0000 0000 溢出,捨棄最高位,是不是又迴歸0了?
     (3)1000 0000 表示的數字是多少?
        1000 0000 表示的數字 是 -128,而不是 -0;
        -----------------------------------------------
        假定有 -0這個數,則在內存中
        1000 0000 
        1111 1111  符號位不變,其他取反
        10000 0000  再加1溢出,捨棄最高位,內存中依然是 0000 0000;
        -----------------------------------------------
        -128的補碼是按照以下方法算的,因爲一個字節最高位是符號位,沒法表示128,所以算的的時候又借了一個字節
        1000 0000  1000 0000  在16位中-128原碼
        1111 1111  0111 1111  取反
        1111 1111  1000 0000  +1得出16位中-128的補碼,存到1字節中,捨棄高位,爲 1000 0000 
       

3 float  double數據的存儲

       float 和 double 數據在內存中的存儲方式相同,只不過由於所佔字節大小不同而導致數值範圍和精度不同。
       以下以float數據爲例,4個字節按照如下分配:
       
       
 
       (1)科學計數法
        對於 十進制數 223.456,換算成科學計數法  2.23456 * 10的2次方     
        對於二進制小數 1101.111 換算成科學計數法 爲 1.10111 * 2的3次方

       (2)在計算機內部,float數的存儲,先換算成二進制的 科學計數法形式,然後分別把 尾數和指數部分存儲到內存中。
         比如  1.10111*2的3次方,則在 8位指數位中要存儲 3 ,23位尾數位要存儲 110111。
         對於二進制數來說,最高位永遠是1 所以最高位1就省略了,23位二進制位其實表示了24位尾數,所以存的是10111,
         由於指數部分有正負 ,範圍是-127--128,在這裏按照移位存儲,3+127 ,所以存儲的是127+3
         對於1101.111在內存中存儲的是如下:
         
       (3)對於以下代碼
               float a = 0.125;
               float b = 0.123;
               根據十進制轉化爲二進制的算法,a是有窮的,並且在23位尾數中可以完全存儲,所有內存中存的就是0.125;
               對於b來說,轉化的二進制數是無窮的,當把尾數放到23位二進制位存儲的時候必然要捨棄低位數據,所以這裏的存儲肯定是不準確的。
               -------------------------------------------------------------------------------------
               所以對於一個  int a_int 來說,可以寫出 if(a_int == 2)這樣的表達式。
               對於 float a_float 來說,不能寫這樣的if(a_float == 1.2)這樣的表達式。
               同樣swtich語句可以switch(a_int),而不能switch(a_float)。



     







         

     




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章