天天看點

[C]有符号數和無符号數

1. 有符号數和無符号數:

    C支援所有整形資料類型的有符号數和無符号數運算。盡管C标準并沒有指定某種有符号數的表示,但是幾乎所有的機器都使用二進制補碼。通常,大多數數字預設都使有符号的,C也允許無符号數和有符号數之間的轉換,轉換原則是基本的位表示保持不變。是以在一台二進制補碼機器上,當從無符号數轉換為有符号數時,效果就是應用U2Tw,而從有符号轉換為無符号數時,就是應用函數T2Uw,其中w表示資料類型的位數。

T2Uw(x) = (x<0)?(x+2w) :x;

U2Rw(x) = (x<2w-1)?x:(x-2w);

[C]有符号數和無符号數

void TestU2T()

[C]有符号數和無符号數

{

[C]有符号數和無符号數

  printf(-2147483647-1==2147483648U?"1 ":"0 ");

[C]有符号數和無符号數

   show_unsignedInt(2147483648U);

[C]有符号數和無符号數

   show_int(-2147483647-1);

[C]有符号數和無符号數

}

2. 擴充數字的位表示:

    當将一個較小的資料類型轉換到一個較大的資料類型時,需要擴充一個數字的位表示。要将一個無符号數轉換為一個更大的資料類型,我們隻要簡單地在表示的開頭添加0,這種擴充稱為零擴充(Zero Extension);要将一個二進制補碼數字轉換為一個更大的資料類型,擴充時需要填充最高有效位的值,這種擴充稱為符号擴充(Zero Extension)。e.g.:

[C]有符号數和無符号數

void TestExtension()

[C]有符号數和無符号數
[C]有符号數和無符号數

   short sx = -12345;

[C]有符号數和無符号數

   unsigned short usx = sx;

[C]有符号數和無符号數

   int x = sx;

[C]有符号數和無符号數

   unsigned ux = usx;

[C]有符号數和無符号數
[C]有符号數和無符号數

   printf("sx=%d ",sx);

[C]有符号數和無符号數

   show_short(sx);

[C]有符号數和無符号數

   printf("usx=%d ",usx);

[C]有符号數和無符号數

   show_unsignedShort(usx);

[C]有符号數和無符号數

   printf("x=%d ",x);

[C]有符号數和無符号數

   show_int(x);

[C]有符号數和無符号數

   printf("ux=%d ",ux);

[C]有符号數和無符号數

   show_unsignedInt(ux);

[C]有符号數和無符号數

運作結果和結果分析:

sx=-12345       cfc7

usx=53191       cfc7

x=-12345    ffffcfc7(符号擴充,算術右移)

ux=53191    0000cfc7(零擴充,邏輯右移)

   另外:從一個資料大小到另一個資料大小,以及無符号和有符号數字之間的轉換的相對順序能夠影響一個程式的行為。e.g.(short sx=-12345): (unsigned)(int)sx != (unsigned)(unsigned short)sx

3. 截斷數字的位表示:

    當将一個較小的資料類型轉換到一個較大的資料類型時,需要截斷該數字的高N位。 

本文轉自Silent Void部落格園部落格,原文連結:http://www.cnblogs.com/happyhippy/archive/2006/12/20/601220.html,如需轉載請自行聯系原作者

繼續閱讀