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。
舍入
- 偶数舍入
将数字向上或者向下舍入,使得结果的最低有效数字是偶数。 - 向零舍入
把整数向下舍入,把负数向上舍入,使得得到的舍入值的绝对值小于等于原值的绝对值。 - 向下舍入
把整数和负数都向下舍入,使得所得的舍入值小于原值。 - 向上舍入
把整数和负数都向上舍入,使得所得的舍入值大于原值。
小结内容
由于编码的长度有限,与传统整数和实数运算相比,计算机运算具有完全不同的属性。当超出表示范围时,有限长度能够引起数值溢出。当浮点数非常接近于0.0,从而转换成零时,也会下溢。
最常见的浮点表示方式是由IEEE标准754定义的。它提供了几种不同的精度,最常见的是单精度(32位)和双精度(64位)。IEEE浮点也能够表示特殊值+∞、-∞和NaN。
必须非常小心地使用浮点运算,因为浮点运算只有有限的范围和精度,而且不遵守普遍的算术属性,比如结合性。
学习中遇到的问题
浮点部分的内容学的很混乱,特别是对于IEEE标准之后的内容,需要重新学习此部分内容。
对于C语言中逻辑运算和位运算真的容易混乱,但我觉得只要掌握住逻辑运算所产生的结果仅为0与1(TRUE和FALSE),且再逻辑运算中,非零的数据即为TRUE这个点就容易区分的多。