计算机系统内的整数表示

用位来编码整数的两种方式:一种只能表示非负数,一种能表示负数、零、正数。

 

1、整型数据类型

C语言支持多种整型数据类型(表示有限范围的正数),每种类型都用关键字来指定大小:char、short、int、long、long long,同时还可以指定数字是非负数(声明为unsigned)。

字节:

char             1字节            

short            2字节              

int                4字节

long             4字节/8字节

long long      8字节

范围:(w二进制位)

有符号(默认)大小: -2^(w-1) ~ 2^(w-1) - 1

无符号(unsigned)大小:       0 ~ 2^w - 1

C和C++都支持有符号(默认)和无符号数,java只支持有符号数。

 

2、整数编码

(1)无符号数的编码只有一种:Binary To Unsigned

         Image(1)

(2)有符号数的编码有多种:补码(two’s complement)、反码(One’s Complement)、原码(Sign-Magnitude)

     反码:最高有效位的权是 -(2^(w-1) -1)

     原码:最高有效位是符号位,用来确定剩下的位应该取负权还是正权

 

3、补码编码

最常用的有符号数的计算机表示方法就是补码(two‘s-complement)。

补码将字的最高有效位解释为负权(negative weight),它的权重为 -2^(w-1);其他位的权重都是正的。无符号数的编码:所有的位的权重都是正的。

补码的函数:

          Image(2)

如:B2T([0101])=-0*8+1*4+0*2+1=5

      B2T([1111])=-1*8+1*4+1*2+1=-1

      B2T([1011])=-1*8+0*4+1*2+1=-5

      Image(3)

补码的范围是不对称的:|TMin|=|TMax|+1

C语言标准并没有要求用补码形式来表示有符号整数,但是几乎所有的机器都是这么做的。


4、有符号和无符号之间的转换

对大多数C语言的实现而言,处理同样字长的有符号数和无符号数之间的相互转换的一般规则是:数值可能会改变,但是位模式不变。

(1)有符号数到无符号数:

        Image(4)

如:-1 => 2^w-1     -2^(w-1) => 2^(w-1)

转换图:

         Image(5)

(2)无符号数到有符号数:

        Image(6)

如:2^(w-1) => -2^(w-1)     2^w-1 => -1

转换图:

         Image(7)

 

示例程序:

int a=0,b=0; 
unsigned int x=-3; //二进制表示:11111111111111111111111111111101 值:4294967293 
a=x<<1; //二进制表示:11111111111111111111111111111010 值:-6
b=x>>1; //二进制表示:01111111111111111111111111111110 值:2147483646

由于许多无符号运算的细微特性,尤其是有符号数到无符号数的隐式转换,会导致错误或者漏洞。避免这类错误的一种方式就是绝不适用无符号数,实际上,除了C,很少有语言支持无符号整数,例如,java只支持有符号整数,并且要求用补码运算来实现。

 

5、C语言中的有符号数和无符号数

1、当声明一个像12345或 0X1A2B这样的常量,默认认为是有符号的。要创建一个无符号常量,需要加上后缀字符 'U' 或 'u'

2、当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式的将有符号数强 制类型转换 为无符号数,并假设两个数都是非负数,来执行这个运算。

 

6、扩展、截断一个数字

(1)扩展一个数字的位数

把一个较小的整数类型转换到一个较大的类型:

  无符号数:零扩展(在开头添加0)

  有符号数:符号扩展(在表示中添加最高有效位的值得副本)

如: short sx=-12345;// 二进制表示:cf c7

        int x=sx;            // 二进制表示:ff ff cf c7

(2)截断一个数字的位数

将一个w位的数截断为一个k位数字时(无符号和有符号都一样),丢弃高w-k位,保留低k位。截断一个数字可能会改变它的值——溢出的一种形式。

 

(转载请注明出处 ^.^)

 

posted @ 2013-03-27 10:28  windlaughing  阅读(1167)  评论(0编辑  收藏  举报