循環小數 強制類型轉換 進行 代碼 size 圖片 unsigned 問題 d+

 在程序設計語言裏,我們會把數據分為各種各樣的類型,為什麽會有數據類型之分呢?計算機中,所有的數據都會表示成二進制數的形式,對於同樣的一個二進制數,數據類型不同,它表示的數據就是不同的。也就是說,同樣的一個二進制數。我們可以把它”翻譯“成不同的數。

  使用一個數據類型的數據的時候,需要註意的問題大概有以下幾種:(1)數據溢出

                                (2)精度問題

                                (3)強制轉換

 (1)數據溢出     

  

#include <stdio.h>
int main()
{
  char d = 255;
  printf("%d",d+1);    
  return 0;  
}

  這段代碼的輸出為0,其實原理很簡單。char類型的數據相當於1個字節的無符號整形,即char型數據的範圍是00000000~11111111,相當於十進制裏的0~255。

  程序中的d是char型數據的最大值,給d加1後,d = 100000000(二進制),由於d是char型數據,所以最高位的1會被計算機丟掉。

  因此,d = 00000000(二進制),即 d = 0;轉化為int型數據後,值依舊是0。

 (2)精度問題

#include <stdio.h>
int main()
{
  float a = 0.1;
  for(int i = 0;i < 100;i++){
    a += 0.1;
  }
  printf("%f",a);       
  return 0;      
}

  運行這段代碼,結果可能會有點出人意料。printf函數打印的結果是

  技術分享圖片

  我們的代碼是沒有問題的,它將100個0.1相加,結果是10。計算機內部的數據是用二進制表示的,十進制永遠無法精確的表示1/3(三分之一),正如二進制,

  永遠無法精確的表示0.1,只能是一個無限循環小數。

  談到無限,在計算機內部,資源總是有限的,我們只能用有限的內存來表示數據,所以,不管是什麽類型的數據,它都是有範圍的,所以,計算機內部不能準

  確的表示一些小數,只能將它控制在一定的精度內。所以我們就看到了這樣的運行結果。

  那麽,如何避免這種精度缺失的問題呢,我們可以把小數,當作整數來算,將一個小數適當的放大,把它變成整數。舉個例子,0.1*10 = 1,這樣,我們就把一

  個難以表示的0.1進行了轉化,然後對計算結果適當的縮小,就可以得到我們想要的結果。我們可以修改上面程序,像這樣:

#include <stdio.h>
int main()
{
   float a = 0.1;
   a *= 10;
   for(int i = 0;i < 100;i++){
        a += 1;
   }  
   printf("%f",a/10);  
   return 0;  
}

  (3)強制類型轉換

   簡單的概括一下強制類型轉換,相對來說,由存儲空間小的類型轉向存儲空間大的類型時,不會發生一些數據溢出,丟失之類的問題,一般來說,危險的轉換發

   生在存儲空間大的類型轉換為存儲空間小的類型。如double->int,float->int,int->char;

 這些時候,程序的結果,往往是出人意料的。 

#include <stdio.h>
int main()
{
   printf("%u\n",unsigned(-1));  
   return 0;  
}

  運行結果為技術分享圖片,是不是有一些出乎意料。我們來分析一下這段代碼,int型的-1在計算機內部的表示形式為     11111111111111111111111111111111(32個1),在將它轉換為unsignefd型數據時,它就會被表示為11111111111111111111111111111111(32個1),

  這樣的話,結果就成了2^32-1,即4294967295,這也是int型數據的最大值。


  



  

  

C語言學習筆記(4)—— 數據類型的使用