《深入理解计算机系统》第二章笔记


本文为《深入理解计算机系统》第二章 信息的表示和处理的笔记,本章主要介绍了无符号数、补码数(整数)和浮点数在计算机中的编码方式和运算规则。了解底层数据的存储原理能让我们写出更安全的程序,避免犯如下这样严重的错误

在这里插入图片描述
在这里插入图片描述

《深入理解计算机系统》原书电子版下载:
深入理解计算机系统(原书第三版).pdf

信息的表示和处理

数字表示

  • 无符号编码:大于0或等于0的数字
  • 补码编码:有符号整数,可以为正或者为负的数字
  • 浮点数编码:实数(以2为基数的科学计数法)

整数编码数值范围较小,但精确;浮点数编码数值范围较大,但只是近似。

一、信息存储

字节:最小的可寻址的内存单位
虚拟内存:机器级程序将内存视为一个非常大的字节数组,称为虚拟内存,
每个字节都有一个数字(地址)标识,地址的集合称为虚拟内存空间

1、寻址和字节顺序

对于跨越字节的程序对象(int,float等),必须有两个规则:

  • 这个对象的地址是?
    对象的地址为所使用字节中最小的地址

  • 在内存中如何排列这些字节?
    大端法:从最高有效字节到最低有效字节的顺序存储
    小端法:从最低有效字节到最高有效字节的顺序存储

    假设int类型的变量x,位于地址0x100处,它的十六进制值为0x01234567。地址范围0x100~0x103的字节顺序(高位字节值为01,低位字节值为67):

大端法
……0x1000x1010x1020x103
01234567
小端法
……0x1000x1010x1020x103
67452301

贴一段印象深刻的代码,作用是按字节打印跨字节对象的地址:

在这里插入图片描述

2、布尔代数(按位运算)

设P和Q:

  • 非(~):P为1时,~P为0;反之为1
  • 与(&):P和Q都为1时,P&Q为1
  • 或(|):P和Q任意一个为1,P|Q为1
  • 异或(^):P为1Q为0或P为0Q为1时,P^Q为1

3、逻辑代数

逻辑代数中,非零为TRUE,0为FALSE,返回0或1分别表示FALSE和TRUE;
逻辑运算与布尔代数运算规则近似,但功能完全不同,举例说明:

  • 非(!):!54 结果为0,!0结果为1
  • 与(&&):12 || 0 结果为0
  • 或(||):0 || 8 结果为1

逻辑短路:如果第一个参数能确定表达式的结果,就不会对第二个参数求值

4、移位运算

  • 左移(<<):向左移动k位,丢弃最高的k位,并在右端补k个0
    例如值为 [01100011] 的数x:x<<4的结果为 [00110000]

  • 右移(>>):右移分为逻辑右移和算术右移:
    - 逻辑右移:在左端补k个0 ;值为[10010101]的数x,x>>4结果为[00001001]
    - 算术右移:在左端补k个最高有效位 ;值为[10010101]的数x,x>>4结果为[11111001]

    有符号数一般使用算术右移,无符号数使用逻辑右移
    Java里没有无符号数,因此明确定义x>>>k为逻辑右移

二、整数表示

数据类型的取值范围由他能分配的字节数决定

1、整型数据类型:

32位整型数据类型取值范围:
在这里插入图片描述
64位整型数据类型取值范围:
在这里插入图片描述

1.1、无符号数(非负数)编码

每个整数都能映射为一个唯一的长度为ω的位模式(十进制–>二进制)
例如二进制(1111)2能映射为唯一的十进制表示(15)10
(1111)2 = 1 × \times × 23 + 1 × \times × 22 + 1 × \times × 21 + 1 × \times × 20= 8 + 4 + 2 + 1 =(15)10
从位到无符号数的映射:
在这里插入图片描述

1.2、补码(整数)编码

将最高有效位解释为负权,负权为1代表该数符号位为负,他的权重为-2ω-1
例如二进制(1111)2 = -1 × \times × 23 + 1 × \times × 22 + 1 × \times × 21 + 1 × \times × 20= -8 + 4 + 2 + 1 =(-1)10
位到补码数的映射:
在这里插入图片描述
补码能表示的范围:
在这里插入图片描述

2、有符号数和无符号数的转换

有符号数和无符号数相互转换规则:保持位值不变,改变这些位的解释方式
例如:有符号数(1011)和无符号数(1011)的值分别为-5和11,相同的位值,解释方式不同值也不同。

在16位机器上,补码数-12345强制类型转换为无符号数后,值为53191
在32位机器上,补码数-1强转为无符号数后,值变为4294967295

3、C语言中的隐式类型转换

在C语言中执行一个运算时,如果一个是有符号一个是无符号的,c会隐式地将有符号转换为无符号数:对关系运算会导致非直观的结果。
例如表达式 -1 < 0U,因为第二个数是无符号的,第一个数会被转隐式转换为无符号数,因此这个表达式等价于4294967295U<0U
如下图,-1明显小于0,但输出的是大于:
在这里插入图片描述
在这里插入图片描述

4、扩展一个数字的位表示

扩展一个数的位数,同时保持数值不变
0扩展:在数的开头添加0
符号扩展:在数的开头添加符号位
无符号数使用0扩展,有符号数使用符号扩展,值才不会改变:

  • 无符号数101扩展至四位0101,还是十进制值5
  • 有符号数101扩展至四位1101,还是十进制值-3

5、截断一个数字的位表示

  • 无符号数:1001截断最高一位变为001,值从9变为1
  • 有符号数:1001截断最高一位变为001,值从-7变为1

上面的这些错误、溢出大部分都是因为使用无符号数造成的,但合理使用无符号数能节省一半的内存空间

三、整数运算

1、无符号加法

两个无符号数相加,如果值超过能表示的范围(2ω),会对他进行截取
从位上很容易理解:
考虑四位无符号 1011 和 0110 相加,值10001超出范围,截取后为0001。即11 + 6 的值由17变成1
截取规则:对ω位的数,进行模2ω运算:17%16 = 1,与上面一致
映射规则:
在这里插入图片描述

无符号加法图示:
在这里插入图片描述

2、补码加法

两个补码数相加,如果值超出范围(大于2ω-1或小于-2ω-1),会进行截取操作
同样从位上理解:
四位补码数1010和1100相加,值10110超出范围,截取后为0110,-6+-4的值从-10变为6
映射规则

补码加法图示
在这里插入图片描述

3、补码的非

对十进制取反操作很容易:
在范围内的数x,除最小值取反还是自己外,其余数取反都为-x例如对9取反值为-9

补码非的位级表示

  • 对每一位求补,再对结果加一
    [0111] → [1000] → [1001]( 7 → -8 → -7)
  • 假设k是最右边的的1的位置,对k左边的所有位取反
    [0111] → [1001] ( 7 → -7)

4、无符号乘法

将一个无符号数截断为ω位,等价于该值模2ω

5、补码乘法

ω位的有符号数相乘,结果可能需要2ω才能表示。
将一个补码数截断为ω位相当于先计算该值模2ω,再把无符号数转换为补码
例如:在这里插入图片描述

6、乘以常数

整数乘法指令相当慢,需要十多个时钟周期。而其他运算(加减、位级运算和移位)只需要一个时钟周期。所以把乘法优化为移位和加法的组合可以提高运行效率。

左移k位等价于乘2的k次幂
例如:四位的数[1011],左移2位得到[101100],值由11变为44,相当于乘22

乘一个较大的数可以把它分解为2的次幂相加的形式:
x * 14 (14 = 23 + 22 + 21)等价于(x<<3)+(x<<2)+(x<<1)

7、除以2的幂

除以2的幂也可以用移位运算来实现,无符号数使用逻辑右移,补码数使用算术右移

无符号数的移位总是舍入到0的结果,与整数除法的规则一致。
在这里插入图片描述

补码数的移位会向下舍入,例如右移4位会把-771.25向下舍入位-772,解决办法是在移位前加一个偏置量:
在这里插入图片描述
偏置量的值为:2k-1(2k为除数)
偏置量的证明:
在这里插入图片描述

最后思考

在这里插入图片描述

四、浮点数

1、二进制小数

浮点数的表示:小数点左边数字的权是正幂,得到整数值;小数点右边数字的权是负幂,得到小数值。
例如:十进制数12.34可以表示为1 * 101+ 2 * 100+ 3 * 10-1+ 4 * 10-2

二进制小数点向左移动一位相当于这个数被2除,向右移一位相当于乘2。

在有限长度编码下,小数的二进制表示法只能表示被写成 x * 2y的数,其他值只能近似表示
例如数字1/5可以用十进制0.20精确表示,但并不能精确表示为一个二进制小数,只能近似的表示它:
在这里插入图片描述

2、IEEE浮点数表示

IEEE标准规定,用: (-1)S × M × 2E 的形式表示一个浮点数。

符号:S决定这数是负数(S=1)还是正数(S=0)
阶码:E的作用是对浮点数加权,权重是2的E次幂
尾数,M是一个二进制小数,M的范围大于等于1,小于2

看图好理解些,如下图,十进制数 5.5 即二进制的 101.1
①把小数点移到最高位后,变成一个大于1小于2的数,即尾数M M=1.011
②移动了2位,即阶码E E=2
③这个数就变为(-1)0 × 1.011 × 22的形式
④在内存里存储只需要存储符号、阶码、尾数就等于存储了这个值
因为指数可以为负,为了便于计算,规定阶码都先加上1023(2^10-1)

符号(1位)阶码(11位)尾数(52位)
010000000001(1023+2)01100000……

在这里插入图片描述
该例为64位的(双精度浮点数Double)格式,符号、阶码、尾数分别占1位、11位和52位)
在32位的(单精度浮点数Float)格式下,符号、阶码、尾数分别占1位、8位和23位

五、小结

在这里插入图片描述
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值