第二章 信息的表示和处理(2.2)

2.2 整数表示

本节描述用来编码整数的两种不同方式:无符号数和有符号数。描述过程相关术语如下图:在这里插入图片描述

2.2.1 整数数据类型

图示为32位与64位整数数据类型的典型取值范围:在这里插入图片描述
在这里插入图片描述
C语言标准定义了每种数据类型必须能够表示的最小取值范围:在这里插入图片描述

2.2.2 无符号数的编码

函数B2Uw是一个双射函数,即U2Bw也成立。
在这里插入图片描述

2.2.3 补码编码

最常见的有符号数的计算机表示方式就是补码形式。
函数B2Tw是一个双射函数,即T2Bw也成立。在这里插入图片描述
w位补码所表示的最小值是位向量为[10…0]即整数值为-2w-1,而最大值是位向量[01…1]即整数值为-2w-1-1。C语言标准并没有要求用补码形式表示有符号整数,但几乎所有机器都是这么做的。Java中,整数数据类型的取值范围和表示都有明确标准。它只支持有符号数,采用补码方式表示,取值与上图64位机器情况一样,单字节用byte取代char。这些具体要求让java程序在什么机器上运行都能完全表现一样。

2.2.4 有符号数和无符号数之间的转换

☆C语言允许在各种不同的数字数据类型之间做强制转换。
C代码:

   short int v=-12345;
     unsigned short uv=(unsigned short)v;
     printf("v=%d, uv=%u\n",v,uv);

输出:

v=-12345,uv=53191

上例中,我们看到强制类型的结果保持位值不变,只是改变了解释这些位的方式。(-12345的补码表示和53191的16位无符号表示是完全一样的,类似:无符号最大值数转换为补码形式的-1时的位模式即位上的01是不变的)。

☆补码转换为无符号数:在这里插入图片描述
☆无符号数转换为补码:在这里插入图片描述
☆小结:在这里插入图片描述

2.2.5 C语言中的有符号数和无符号数

☆C语言中声明一个像12345的常量时,默认为有符号,否则必须加上后缀u或U。一台采用补码的机器都会采用上述转换方法。当执行一个运算时,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式地将有符号参数转换为无符号数,并假设两者都是非负的,来执行运算(看到这里我又想念java了)。

☆考虑比较式-1<0u(假设-1为4字节int类型)。因为第二个运算符是无符号的,第一个运算符就被转换为无符号数,因此表达式等价于4294967295u<0u。答案自然是错的。

2.2.6 扩展一个数字的位运算

从一个较小的数据类型转换到一个较大的类型,总是可能的。
☆零扩展:在这里插入图片描述
要将一个无符号数转换为一个更大的数据类型,我们只要简单在表示的开头添加0。
☆符号扩展(2w-2w-1=2w-1):
在这里插入图片描述

2.2.7 截断数字

int x = 53191;
short sx = (short) x;   	 /* -12345 */
int y=sx;			 /* -12345 */

当我们把x强制转换为short时,我们就将32位的int截断为16位的short int。由于最高位必须表示符号位,16位时就是-12345的补码表示。当我们把它强制转换为int时,符号扩展就把新增的前16位设置为1,从而变成32位的-12345补码表示。

☆截断无符号数:在这里插入图片描述

☆截断补码数值:在这里插入图片描述

2.2.8 关于有符号数和无符号数的建议

除了C语言以外,很少有语言支持无符号整数,应尽量避免使用无符号数。而当我们把字仅仅看做位的集合而没有数字意义时,无符号数值就很有用了,例如在一个字中放入描述各种布尔条件的标记时,存放地址时,等等。

猜你喜欢

转载自blog.csdn.net/ao__ao/article/details/82929925
今日推荐