深入理解计算机系统--第二章(读书笔记)

来源:互联网 发布:富士康网络重复报名 编辑:程序博客网 时间:2024/05/18 03:09

由于这章内容比较多,比较枯燥,需要耐心阅读才可以。只把把主要内容知识点列出,具体细节再单独查看相关资料进行详细了解。

1.大端和小端存储

小端存储:机器在存储器中按照最低有效字节到最高有效字节的顺序存储对象,也就是说最低有效字节在前面,Intel的机器就是这样。

大端存储:机器按照最高有效字节到最低有效字节的顺序存储对象,例如IBM,Sun Microsystems的大多数机器

2.十六进制、二进制、十进制之间的转换问题

3.溢出问题

4.位级运算

5.整数运算

6.浮点数运算

7.舍入问题计算机中数据的舍入有4种方式1:向偶数舍入(四舍六入五成双)2:0舍入3:向上舍入4:向下舍入

8. 另外浮点运算与其他两种运算相比有完全不同的数学属性。虽然溢出会产生特殊的值+∞,但是一组正数乘积总是正的。另一方面由于表示的精度有限,浮点运算是不可结合的。例如,在大多数机器上,C表达式(3.14+1e20)-1e20求得值会是0.0,而3.14+(1e20-1e20)求得的值会是3.14.

给力总结如下:

1.三种重要的数字表示区别

(1)无符号编码基于传统的二进制表示法,表示大于或者等于零的数字

(2)补码编码是表示有符号整数的最常见的方式,即可以为正也可以为负的数字

(3)浮点数编码是表示实数的科学记数法的以二为基数的版本。

2. 无符号数右移必须采用逻辑右移,而有符号数一般采用算术右移,C语言中的移位运算:对于无符号数据,右移必须是逻辑的,对于有符号数据,算数的或者逻辑的右移都可以。算数右移时,若最高位是1,填充的就是1。

3. 有符号数遇见无符号数会默认强转为无符号数。

4. 浮点加法和乘法不具备结合性,浮点乘法在加法上不具备分配性。

//以下是其他博客总结的

1,由于表示的精度有限,浮点运算时不可结合的,一般是选择最小的先运算。
2,字长指明整数和指针数据的大小。字长决定的最重要的系统参数是虚拟地址空间的最大大小。
3,float一般为4字节,double一般为8字节,指针一般用的是全字长,32位机上是4字节,64位机上是8字长。

4,在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节序列中最小的地址。
5,二进制代码很少能在不同机器和操作系统组合之间移植。
6,表达式~0将生成一个全1的掩码,不管机器的字大小是多少。尽管对于一个32位机器同样的掩码可以写出0xFFFFFFF,但是这样的代码是不可移植的。
7,几乎所有的编译器/机器组合都对有符号数据使用算术右移,即在左边补充符号位。
8,C和C++都支持符号和无符号数,但JAVA只支持有符号数。
9,C库中的文件<limits.h>定义了一组常量,用来限定运行编译器的这台机器的不同整形数据类型的范围,如INT_MAX,INT_MIN,UINT_MAX。
10,强制类型转换并没有改变参数的位表示,只是改变了如何将这些位解释为一个数字:
 int x = -1;
 unsigned ux = (unsigned)x;
 这里的ux = 0xffff ffff
11,规则1:当将一个有符号数映射为它相应的无符号数时,负数就被转换成了大的正数,而非负数会保持不变。
规则2:对于小的数(<2^(w-1)),从无符号到有符号的转换将保留数字的原值,对于大的数,数字将被转换为一个负数值。
12,无符号整数加法: 

   x+y = x+y,            x+y<2^w
   x+y = x+y-2^w     x+y>=2^w
13,有符号整数加法: 
x+y = x+y-2^w,           x+y >= 2^(w-1) 正溢出
x+y =x+y,                    正常
x+y =x+y+2^w,           x+y< -2^(w-1) 负溢出
14,二进制补码的非
-x = -2^(w-1),     x = -2^(w-1)
-x =-x,                x > 2^(w-1)
15,在单精度浮点格式(C中的float)中,s,exp和frac分别为1位,8位,23位,产生一个32位的表示。在双精度格式(C中的double)中,s,exp和frac分别为1,11位,52为,产生一个64位的表示。
16,浮点数的舍入规则是向偶数舍入(round-to-even),或者向最接近的值舍入(round-to-nearest)。
17,浮点加法不具有结合性,浮点加法满足下面的单调性属性:如果a>=b,那么对任何a和b的值,除了x不等于NaN,都有x+a>=x+b。浮点乘法也满足相应的单调性属性。
18,浮点数取非就是简单的对它的符号位去反。float f; f == -(-f)是正确的。

19,看下面这段代码

[cpp] view plaincopy

1.  #include <iostream>  

2.  #include <iomanip>  

3.  using namespace std;  

4.    

5.  void main()  

6.  {  

7.      double x = 1.3;  

8.          double y = 0.4;  

9.          if (x + y != 1.7)   

10.             cout << "addition failed?" << endl;  

11. }  

12.    

运行结果将是additionfailed?"。也就是x+y != 1.7原因就是double中保存的是近似值,而不是精确值1.7.

正确的写法应该如下:

[cpp] view plaincopy

1.  #include <iostream>  

2.  #include <iomanip>  

3.  using namespace std;  

4.    

5.  const double epsilon = 0.000001;  

6.    

7.  bool about_equal(double x, double y)  

8.  {  

9.      return (x < y + epsilon) &&  

10.            (x > y - epsilon);  

11. }  

12.   

13. void main()  

14. {  

15.     cout << "1.3 + 0.4 == 1.7: " <<   

16.             (1.3 + 0.4 == 1.7) << endl;  

17.     cout << "about_equal(1.3 + 0.4, 1.7): " <<  

18.             about_equal(1.3 + 0.4, 1.7) << endl;  

19.

 

0 0