Linux第三次学习笔记

信息的表示和处理


三种重要的数字表示

1. 	无符号数编码:
	基于传统的二进制表示法,表示大于或者等于零的数字。
2.  补码编码:
	表示有符号数整数的最常见的方式,有符号数就是只可
	以为正或者为负的数。
3.  浮点数编码:
	表示实数的科学计数法的以二为基数的版本。

进制转换

太过于熟悉,此处就不详细说明,注意当转换的起始值和终止值
均不为二进制时,将二进制作为中间过渡将会容易很多。
例如:十六进制→八进制 转换为 十六进制→二进制→八进制

进制运算

进行n进制运算(加减乘除),基数则为n.
例如练习题2.4中 0x503c+0x8=?
∵0x8+0xc=0x14
∴0x503c+0x8=0x5044

每台计算机都有一个字长,指明整数和指针数据的标称大小。

数据大小

—————————————————————————————————————————————————————————
C声明    	     |	32位机器 	|	64位机器
—————————————————————————————————————————————————————————
char	             |     1	 	|    	1
—————————————————————————————————————————————————————————
short int            |	   2		|	2	
————————————————————————————————————————————————————————
int		     |	   4		|	4	
—————————————————————————————————————————————————————————
long int  	     |	   4		|	8	
—————————————————————————————————————————————————————————
long long  int       |	   8		|	8	
—————————————————————————————————————————————————————————
char *               |     4		|	8	
—————————————————————————————————————————————————————————
float                |	   4		|	4	
—————————————————————————————————————————————————————————
double               |	   8		|	8	
—————————————————————————————————————————————————————————

寻址和字节顺序

考虑一个w位的整数,位表示位[Xw-1,Xw-2,···,X1,X0],
其中Xw-1是最高有效位,而X0是最低有效位。
如果w为8的倍数,则可将这些位分组为字节,其中最高有效字节包含
位[Xw-1,Xw-2,···,Xw-8],而最低有效字节包含[X7,X6,···,X0]
★若机器按照从最低有效字节到最高有效字节的顺序存储对象,则称为
小端法。相反,若机器按照从最高有效字节到最低有效字节的顺序存储对
象则成为大端法。

*例子详见教材P26

书本p28页代码:

强制类型转换来访问和打印不同程序对象的字节表示。
结果如下:

不同数据值的字节表示,除了字节顺序意外,int和float的结果是一样的。
指针值与及机器相关。

布尔代数

__________________________________________
    布尔运算   |  逻辑运算    |	命题逻辑
——————————————————————————————————————————
	  ~   |    NOT	      |    ┐
__________________________________________
	  &   |    AND	      |    ∧
__________________________________________
	  |   |    OR	      |	   ∨
__________________________________________
	  ^   |   异或	      |	   ⊕
__________________________________________

&对|的分配律:
a&(b|c) = (a&b)|(a&c)

|对&的分配律:
a|(b&c) = (a|b)&(a|c)

每个元素的加法逆元时它本身,即对于任意值a,存在a^a=0
(这里的0表示全0的位向量)

重新排列组合顺序,这个属性也仍然成立。例如(a^b)^a=b

位向量一个有用的应用就是表示有限集合。我们可以用位向量
[Aw-1,···,A1,A0]编码任意子集A⊆{0,1,···,w-1},其中
Ai=1当且仅当i∈A。例如,位向量a=[01101001]表示集合A=
{0,3,5,6}。

掩码

位向量掩码可以有选择地使能或是不能屏蔽一些信号,其中某一位位置上位1时,
表明信号i是有效的,而0表明该信号是被屏蔽的。即表示的是设置为有效信号的
集合。(对特定位可以置疑,可以清零)

C语言中的逻辑运算

C语言中逻辑运算符

||  相对应  OR

&&  相对应  AND

!  相对应  NOT

★逻辑运算认为所有非零的参数都表示TRUE且返回1,而参数0表示FALSE
  且返回0.

★逻辑运算如果对第一个参数求职就能确定表达式的结果,那么逻辑运算符
  就不会对第二个参数求值。

★逻辑运算针对的不是具体数值的与或非的运算,而是TRUE与FALSE的运算。
  例如0x66&&0x39,0x66为TRUE、0x39为TRUE所以结果为TURE即0x01

C语言中的移位运算

1.左移(x<<k)
  x向左移动k位,丢弃最高的k位,并在右端补k个0.
2.右移(x>>k) 
  逻辑右移:x向右移动k位,丢弃最高的k位,并在左端补k个0.
  算术右移:x香油移动k位,丢弃最高的k位,并在左端补k个最高有效为的值。
★对于无符号数据,右移必须是逻辑的。对于有符号数,算术或逻辑右移均可以。

整数的表示

具体数据类型的表示范围在教材P38此处不予体现。

要用C99中的"long long"类型,编译要用gcc -std=c99

无符号数的编码:

补码编码:

补码的范围是不对称的:|TMin| = |TMax| + 1,也就是说,TMin没有
与之对应的正数。

补码的利用寄存器的长度是固定的特性简化数学运算。想想钟表,12-1 
等价于 12 + 11,利用补码可以把数学运算统一成加法,只要一个加法器
就可以实现所有的数学运算。(应正确理解补码)

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

1.无符号数--->有符号数

看无符号数的最高位是否为1,如果不为1(为0),则有符号数就直接等于无符号数;如果无符号数的最高位为1,则将无符号数取补码,得到的数就是有符号数。

2.有符号数--->无符号数

看有符号数的最高位是否为1,如果不为1(为0),则无符号数就直接等于有符号数;如果有符号数的最高位为1,则将有符号数取补码,得到的数就是无符号数。

总结:有符号数与无符号数之间的转换,都要看要转换的数的最高位是否为1,如果不为1,则转换结果就是要转换的数的本身;如果为1,则转换结果就是转换的数(看作是负数)的补码。

C语言中的有符号数与无符号数

★当C语言对同时包含有符号和无符号数表达式执行运算时,会将有符号数强制转换为无符号数,再进行运算。

扩展一个数字的位表示

零扩展:

将一个无符号数转换为一个更大的数据类型,我们只需要简单地在表示的开头添加0。

符号扩展:

将一个补码数字转换为一个更大的数据类型可以执行符号扩展(sign extension),规则是在表示中添加最高有效位的值的副本。

整数运算

无符号加法

w表示最大表示位,当x+y>2^w-1,其和溢出

补码加法

例子在教材p58展示

补码的非

无符号乘法

w位无符号乘法运算* wu的结果为:

补码乘法

C语言中的有符号乘法是通过将2^w位的乘积截断为w位的方式实现的。根据等式,w位的补码乘法运算* wt的结果为:

示例见教材p61

乘以常数

14可以写成[(0...0)(111)(0)]。考虑一组从位位置n到位位置m的连续的1(n ≥ m)。(对于14来说,我们有n = 3和m = 1。)我们可以用下面两种不同形式中的一种来计算这些位对乘积的影响:

除以2的幂

★无符号数除以2的幂
x>>k等价于x/(2^k)

★有符号数除以2的幂
1.非负数同无符号数
2.x>>k(算术右移),结果同除以2的幂几乎完全一样

浮点数

浮点表示对形如V = x×2y的有理数进行编码。它对执行涉及非常大的数字(|V |>>0)、非常接近于0(|V |<<1)的数字,以及更普遍地作为实数运算的近似值的计算,是很有用的。

IEEE浮点表示

IEEE浮点标准用V = (-1)^s × M × 2^E的形式来表示一个数:

符号(sign) s决定这个数是负数(s=1)还是正数(s=0),而对于数值0的符号位解释作为特殊情况处理。

尾数(significand) M是一个二进制小数,它的范围是1~2-ε,或者是0~1-ε。

阶码(exponent) E的作用是对浮点数加权,这个权重是2的E次幂(可能是负数)。

将浮点数的位表示划分为三个字段,分别对这些值进行编码:

一个单独的符号位s直接编码符号s。

k位的阶码字段exp = ek-1…e1e0编码阶码E。

n位小数字段frac = fn-1…f1 f0编码尾数M,但是编码出来的值也依赖于阶码字段的值是否等于0。

舍入

  1. 偶数舍入
    将数字向上或者向下舍入,使得结果的最低有效数字是偶数。
  2. 向零舍入
    把整数向下舍入,把负数向上舍入,使得得到的舍入值的绝对值小于等于原值的绝对值。
  3. 向下舍入
    把整数和负数都向下舍入,使得所得的舍入值小于原值。
  4. 向上舍入
    把整数和负数都向上舍入,使得所得的舍入值大于原值。

小结内容

由于编码的长度有限,与传统整数和实数运算相比,计算机运算具有完全不同的属性。当超出表示范围时,有限长度能够引起数值溢出。当浮点数非常接近于0.0,从而转换成零时,也会下溢。

最常见的浮点表示方式是由IEEE标准754定义的。它提供了几种不同的精度,最常见的是单精度(32位)和双精度(64位)。IEEE浮点也能够表示特殊值+∞、-∞和NaN。

必须非常小心地使用浮点运算,因为浮点运算只有有限的范围和精度,而且不遵守普遍的算术属性,比如结合性。

学习中遇到的问题

浮点部分的内容学的很混乱,特别是对于IEEE标准之后的内容,需要重新学习此部分内容。

对于C语言中逻辑运算和位运算真的容易混乱,但我觉得只要掌握住逻辑运算所产生的结果仅为0与1(TRUE和FALSE),且再逻辑运算中,非零的数据即为TRUE这个点就容易区分的多。

posted @ 2015-10-04 20:06  20135212池彬宁  阅读(527)  评论(1编辑  收藏  举报