您的位置:首页 > 理论基础

计算机系统内的整数表示

2013-03-27 10:28 183 查看
用位来编码整数的两种方式:一种只能表示非负数,一种能表示负数、零、正数。

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





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

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

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

3、补码编码

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

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

补码的函数:





如: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





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

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

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

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

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





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

转换图:





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





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

转换图:





示例程序:

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、[b]扩展、截断一个数字[/b]

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

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

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

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

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

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

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

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

(转载请注明出处 ^.^)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐