要点概括:
一、三种最重要的数字表示:
无符号数,有符号数(二进制补码),浮点数
从逆向考虑为什么产生漏洞:
结果太大不能表示时产生溢出,得到了负的结果。
二、信息存储
1.进制转换:以二进制作为桥梁。
2.字长:32位 64位
3.数据大小:单精度(4字节),双精度(8字节)
4.声明指针:
对于任何数据类型T,声明
T *p;
表明p是一个指针变量,指向一个类型为T的对象。
5.gcc –m32 可以在64位机上生成32位的代码。
6.寻址和字节顺序:
字节顺序是网络编程的基础。小端是“高对高,低对低”,大端则与之相反。
7.P28代码:
用typedef将数据类型byte_pointer定义为一个指向类型为“unsigned char"的对象的指针。
8.布尔代数:
(1)逻辑运算:
所有逻辑运算都可以用与、或、非表达。而与或非可以用”与非“”或非“表达。所以,只需要一个与非门,就可以实现所有的数学运算。
(2)位运算:
位向量:有固定长度为w,由0和1组成的串。
位向量的运算:参数每个对应元素之间的运算,例如a和b向量组相对应的&,|,^,~
9.掩码:
我们可以通过指定一个位向量掩码,有选择的使能或是不能屏蔽一些信号。
其中某一位置上为1时,表明信号i是有效的;而0表明该信号是被屏蔽的。
因而,这个掩码表示的就是设置为有效信息的集合。
10.C语言中的位级运算:
C语言支持布尔运算。
确定一个表达式最好的方法,就是讲十六进制的参数扩展为二进制并且执行二进制运算,然后再转换回十六进制。
11.C语言中的逻辑运算:
逻辑运算符
逻辑运算认为所有非0的参数都表示TRUE,而参数0表示FALSE,它们返回1或者0,分别表示结果为TRUE或者FALSE。
12.C语言中的移位运算:
x<<k表示x向左移动k位,丢弃最高的k位,并在右端补k个0.
算数右移是在左端补k个最高有效位的值。
三、整数表示
1.数据类型long long是在ISO C99中引入的,它需要至少8个字节表示。
2.补码编码:
补码的利用寄存器的长度是固定的特性简化数学运算。类似于钟表。
利用补码就可以把数学运算统一成加法,只要一个加法器就可以实现所有的数学运算。
3.有符号数和无符号数的转换:
位向量不变。信息就是位+上下文。
4.怎么样让正数等于负数:
在负数x后加上U,可以使其转换为(2^w+x)
5.零扩展:将一个无符号数转换为一个更大的数据类型,简单地在前面加上0。
类似于逻辑左(右)移。
符号扩展:将一个补码数字转换为一个更大的数据类型,在表示中添加最高有效位值的副本。
类似于算数左(右)移。
6.截断数字:将一个w位的数截断为一个k位的数字时,我们会丢弃高w-k位(二进制)。
得到一个位向量为:2^w mod 2^k,有可能发生溢出.
四、整数运算:
1.如何让整数运算溢出?如何避免?
算数运算的溢出是指完整的整数结果不能放到数据类型的字长限制中去。两个数的和为2^w或者更大时,就发生了溢出。
2.关于整数运算的最后思考:
实际上是一种模运算的形式;提供了一种既能表示负数也能表示正数的灵活方法。同时使用了与执行无符号算数相同的位级实现。
3.浮点数的不精确性与舍入:
浮点数对形如V = X*2^Y的数字进行编码,主要是很接近于0或者很大的数字。
当一个数字不能被精确地表示为这种形式时,就必须要向上或者向下调整,即为舍入。
五、浮点数
1.IEEE浮点标准:
用V= (-1)^sM2^E来编码一个数。
符号:s决定这个数是负数(s=1)还是正数(s=0),对于数值是0的符号位解释为特殊情况。
尾数:M是一个二进制小数 阶码:E对浮点数加权,可以是负数
float:s=1位,exp=8位,frac=23位
double:s=1位,exp=11位,frac=52位
2.整数与浮点数表示同一个数字的关系:
p74:相关区域对应整数的低位,刚好在等于一的最高有效位之前停止,和浮点表示的小数部分的高位相匹配的。
3.整数与浮点数转换规则:
整数转化成浮点数:
整数先化成二进制,小数点左移若干位得到规格化表示,取出小数部分的数值,在后面补0使其达到23位;
用frac加上偏置量得到的结果用二进制表示,放在取出的部分前面,再加上一个符号位即可得到。
(习题做在书上了)
六、思考与感悟:
这一章的学习主要存在的问题就是要不断地用新的思维重新认识之前所学的内容。为什么这样,怎么解释的。有一些公式最重要的是理解。
我一开始不理解截断IEEE浮点的知识,认为太艰涩难懂了,但是后来看了别人的总结,换了不同的方式理解,也马马虎虎认识了些。
还有关于数据类型的掌握方面还需要走很长的路,但我会努力的。