天天看点

[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,如需转载请自行联系原作者

继续阅读