zoukankan      html  css  js  c++  java
  • 2018-2019-1 20189206 《深入理解计算机系统》第二章学习笔记

    2018-2019-1 20189206 《深入理解计算机系统》第五周学习总结

    教材学习内容总结

    本章主要研究三种重要的数字表示,分别是无符号编码、补码编码和浮点数编码。其中,无符号编码表示大于或等于零的数字,补码编码用来表示有符号整数,浮点数编码是科学计数法的以2为基数的版本。

    第二章 信息的表示和处理

    信息存储的方式

    1. 最小可寻址的内存单位————8位的块,也称为字节
    2. 机器级程序将内存视为一个非常大的数组,称为虚拟内存
    3. 内存的每个字节都由唯一的数字来表示,称为地址

    十六进制表示方式

    1. 一个字节的
      对应的二进制表示为 (00000000_2 至 11111111_2)
      对应的十进制表示为 (0_{10} 至 255_{10})
      对应的十六进制表示为 (00_{16} 至 FF_{16})(以0x或者0X开头的数字为十六进制表示)

    2. 特殊的转换方法

      当值x是2的非负整数的n次幂时即 $$x=2^n$$ 可以将x写成1后面加n个0的形式。
      当n表示为 n=i+4j 时(0<=i<=3),x对应的十六进制数字可以写成1、2、4、8后面跟J个0
      例如: $$ 512 = 2^9 $$ 知 n=1+2*4 故2048对应的16进制是 0x200

    字数据大小

    1. 每个计算机都有一个字长,用来指明指针数据的标称大小。 字长决定的最重要的系统参数就是虚拟地址空间的最大大小。对于一个字长为w的机器,虚拟地址的范围为$$ 0 至 2^w -1 $$程序最多访问2^w个字节。
    2. 多字节对象被存储为连续的字节序列,对象的地址为使用字节中最小地址
      • 大端法:最高有效字节存储在前面(即先存储最高有效字节)
      • 小端法:最低有效字节存储在前面(先存储最低有效字节)
      • 假设0x01234567
        • 大端法存储为 01 23 45 67 (地址从左至右增大)
        • 小端法存储为 67 45 23 01 (地址从左至右增大)
    3. linux32 Windows和linux64 均为小端机器,可以记为阅读顺序和存储顺序相反。

    下面show_bytes函数的作用是打印出每个以十六进制表示的字节,其中输入是一个字节序列的地址。

    void show_bytes(byte_pointer start,size_t len)
    {
    	size_t i;
    	for(i=0;i<len;i++)
    	{
    		printf("%.2x",start[i]);
    	}
    	printf("
    ");
    }
    
    void show_int(int x)
    {
    	show_bytes((byte_pointer)&x,sizeof(int));
    }
    

    实现的功能就是输出int型每个字节对应的十六进制表示。

    布尔代数

    	布尔运算     逻辑运算    命题逻辑
    	   ~          NOT        ┐
    	   &          AND        ∧
           |          OR         ∨
           ∧         异或        ⊕
    
    • 位级运算的常用用法是实现掩码运算,掩码表示从一个数中选出的位的集和。
      x & 0xFF 得到的结果就是x最低有效字节组成的值,其余字节被置0,之后表达式~0 得到的结果就是全为1 的掩码。

    【注】注意区分C语言中的逻辑运算与位级运算

    C语言的逻辑运算是|| &&和!,分别对应命题逻辑中的OR、AND和NOT运算。逻辑运算认为所有的非零值都为真,参数零表示假,运算结果只由0和1。
    

    逻辑运算中如果第一个参数求值就能确定表达式的值,逻辑运算不会对第二个参数求值

    位移运算

    • 位移运算分为左移和右移
      • 左移 X向左移,丢弃最高的k位,并在右端补0
      • 右移 X向右移,丢弃最低的k位
        • 算数右移 在左端补k个最高有效位的值
        • 逻辑右移 在左端补0

    几乎所有的编译器/机器组合都会对有符号数使用算数右移,而对于无符号数,右移必须是逻辑右移。

    整数表示

    无符号数只能表示非负数,而补码编码能够表示负数、0和正数。

    • 无符号数的编码

      • 无符号数的定义
        对于向量 $$ vec{x} = [x_{w-1},x_{w-2},cdots,x_0] $$ 有

        [B2U_w (vec{x}) = sum_{i=0}^{w-1}x_i2^i ]

      • 无符号数所能表示的值的范围
        [0 0 …… 0] 到 [1 1 …… 1]即

        [UMax_w = sum_{i=0}^{w-1}2^i = 2^w-1 ]

      • 无符号编码的唯一性
        函数B2U是一个双射,将每一个长度为w的位向量,映射为0~2^w-1之间的唯一一个值,这种映射是一一对应的关系,即可以反向操作。

    • 补码编码
      最常见的有符号数的计算机表示方式就是补码形式,这种形式下,将字的最高有效位解释为负权。

      • 补码编码的定义

      对于向量 $$ vec{x} = [x_{w-1},x_{w-2},cdots,x_0] $$ 有

      [B2T_w (vec{x}) = -x_{w-1}2^{w-1} + sum_{i=0}^{w-1}x_i2^i ]

      最高有效位称为符号位,符号位为1时,表示值为负数;符号值为0时,值为非负。

      • 补码所能表示的范围

      它能表示的最小值是[1 0 …… 0] 其整数值为 $$TMin_w = -2^{w-1} $$
      最大值为[0 1 …… 1] 其整数值为$$TMax_w = sum_{i=0}{w-1}2i = 2^w-1$$

      • 补码有着与无符号数相同的双射函数
      • 最大无符号数刚好比补码的最大值的两倍大一$$UMax_w=2TMax_w + 1 $$

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

    • 强制类型转换的结果保持位不变,只是改变了解释这些位的方式。处理同样字长的有符号数和无符号数之间的转换一般规则是:数值可能会改变,但是位模式不变

    • 补码转换为无符号数

    对满足$$TMin_wleq x leq TMax_w $$的x有:

    [T2U_w(x) =egin{cases} x+2^w & x <0 \ x & x geq 0 end{cases}]

    从以上表达式可以看出,将一个有符号数转为它相应的无符号数时,负数就被转换成了大的整数,非负数则会保持不变。

    • 无符号数转换为补码

    对满足$$0 leq u leq UMax_w $$的x有:

    [U2T_w(u) =egin{cases} u & x leq TMax_w \ u-2^w & u>TMax_w end{cases}]

    从以上表达式可以看出,讲一个无符号数转换为补码时,U2T把大于2^w-1的数转化成了负数。

    从上述两个公式可以看出,对于在范围$$ 0 leq x leq TMax_w $$的范围内的数字有着相同的补码和无符号数表示。对于这个范围以外的数需要加上或者减去2^w

    • C语言中,当执行一个运算时,它的一个运算数是有符号的,另一个运算数是无符号的,那么C语言会将有符号数强制类型转换为无符号数,并假设这两个数都是非负的。

    扩展一个数字位的表示

    1. 将无符号数转换为一个更大的数据类型——零扩展
    2. 将补码转换为一个更大的数据类型——符号扩展(添加最高有效位的值)

    截断数字

    1. 截断无符号数

    令$$vec{x} = [x_{w-1},x_{w-2},cdots,x_0]$$ 现截断该位向量k位的结果是$$x' = x mod 2^k$$

    1. 截断补码数值
      令$$vec{x} = [x_{w-1},x_{w-2},cdots,x_0]$$ 现截断该位向量k位的结果是$$x' = U2T_k(x mod 2^k)$$即把最高位的权重从正变为负。

    整数运算

    • 无符号加法
      定义无符号数加法,该操作是把整数和x+y截断为w位得到的结果,再把这个结果看作是一个无符号数。可以被看作是一种形式的模运算
      对于x、y满足$$ 0 leq x,y<2^w $$有:

    [x + y =egin{cases} x+y & x+y leq 2^w \ x+y-2^w & 2^w leq x+y <2^{w+1} end{cases}]

    当x+y的结果s小于x或者小于y的时候,可以判定无符号数的加法出现了溢出。

    • 无符号数求反

    模数加法形成了一个阿贝尔群,对于每个x值必定有有一个加法逆元。
    对于满足$$ 0 leq x <2^w $$的任意x值,其无符号加法逆元为

    [- x =egin{cases} x & x=0 \ 2^w-x & x>0 end{cases}]

    • 补码加法
      对于满足$$-2^{w-1} leq x,y leq 2^{w-1}-1 $$的整数x和y 有

    [x + y =egin{cases} x+y-2^w & 2^{w-1} leq x+y & 正溢出 \ x+y & -2^{w-1} leq x+y <2^{w-1} &正常\ x+y+2^w & x+y<-2^{w-1} & 负溢出 end{cases}]

    • 补码的非
      对于满足$$ TMin_w leq x <TMin_w $$的任意x值,其补码的非为

    [- x =egin{cases} TMin\_w & x=TMin\_w \ -x & x>TMin\_w end{cases}]

    • 无符号和补码乘法
      将一个数截断w就等价于计算该值的模2^w
      对于无符号和补码乘法来说,乘法运算的位级表示都是一样的。

    • 乘以常数

    由于在大多数机器上,整数乘法的指令需要10个或者更多的时钟周期,其他整数运算只需要1个时钟周期。编译器使用了优化,试着用位移和加法的运算组合代替乘以常数因子的乘法。
    原理: 设x的位模式为 ([x_{w-1},x_{w-2},cdots,x_0])表示无符号整数,那么对于任何$k leq 0 $都认为 ([x_{w-1},x_{w-2},cdots,x_0,0,0,cdots,0]) 给出了 (x*2^k) 的w+k位的无符号表示,右边增加了k个0。
    可以看出,左移一个数值相当于执行一个与2的幂相乘的无符号乘法

    例如:一个程序包含表达式 x*14 利用 $14 =23+22+2^1 $ 可以将该乘法重写(x<<3)+(x<<2)+(x<<1),将一个乘法替换为位移和两个加法。
    或者利用 $14 =24-21 $ 重写成 (x<<4)-(x<<1)

    • 除以2的幂
      • 除以2的幂的无符号除法
        假设有无符号数值x和k,且 $0 leq k <w $ 则表达式 x>>k 产生结果(lfloor x/2^k floor)
      • 除以2的幂的补码除法
        假设有补码数值x和无符号数值k,且 $0 leq k <w $ 则表达式执行算术位移 x>>k 产生结果(lfloor x/2^k floor)

    浮点数

    • 二进制小数
      表示方法:$ b_m b_{m-1} cdots b_1 b_0.b_{-1} b_{-2} cdots b_{-n} $
      这个表达描述的定义如下:

    [b = sum_{i=-n}^{m}2^i*d_i ]

    • IEEE浮点表示
      • 浮点标准用$$ V= (-1)^s * M * 2^E $$ 来表示一个数

        • 符号:s决定了这个数是负数(s=1)还是正数(s=0)
        • 尾数:M是一个二进制小数,范围是1~2-ε 或者 0~1-ε
        • 阶码:E的作用是对浮点数加权,这个权重是2的E次幂
      • 将浮点数的位表示划分为3个字段,分别对这些值编码

        • 一个单独的符号位s
        • k位的阶码字段(exp=e_{k-1} cdots e_1 e_0)编码阶码E
        • n位的小数字段$frac=f_{n-1} cdots f_1 f_0 $编码尾数M
      • 规格化的值

        • exp的位模式不会全为0或全为1 阶码字段被表示为以偏置形式表示的有符号整数。E= e-bias e为无符号数 (bias=2^{k-1}-bais)
        • 小数字段frac,尾数定义为M=1+f
      • 非规格化的值

        • 阶码E全为0时是非规格化的形式,此时 E=1-Bias 尾数值M=f
      • 特殊值

        • 阶码全为1时,得到的值表示无穷

    【注】浮点运算只由有限的范围和精度,并且不遵守结合律。

    总结

    本章重点在于用数学公式准确定义出计算机中使用的几种数据类型,内容很多,需要好好总结和复习。通过直接操作数字级的位表示,得到了几种算数运算的方式。针对不同的机器,变量类型存储的大小也不同、存储方式不同,为了能使编写的程序在全部范围内正确工作,可以实现跨越不同的机器、操作系统和编译器的组合,对于这种数学原理的学习是十分重要的。
    第二章主要从信息存储的方式、整数表的方法(无符号编码、补码编码)以及相关操作、整数运算(无符号运算、补码运算)、浮点数(两种表示方式)等方面介绍了数据的存储表示方式,进行计算的结果等内容。

  • 相关阅读:
    HDU 2563 统计问题 (DFS + 打表)
    KendoUi中KendoDropDownList控件的使用——三级级联模块的实现
    POJ 1325 &amp;&amp; ZOJ 1364--Machine Schedule【二分图 &amp;&amp; 最小点覆盖数】
    crontab FAQ
    思科2960trunk vlan配置及路由IP配置
    hdoj-1593-find a way to escape【数学题】
    Java编程思想(四) —— 复用类
    在 Android 应用程序中使用 SQLite 数据库以及怎么用
    Swift Standard Library Reference.pdf
    VC、IE、ASP环境下打印、预备的完美解决方式
  • 原文地址:https://www.cnblogs.com/zz-1226/p/9887885.html
Copyright © 2011-2022 走看看