02:信息的表示和处理
- 信息的存储:虚拟地址空间、字节和比特、字长
- 整数的表示(原码、反码和补码)、整数运算
- 浮点数的表示的运算
文章目录
1. 信息的存储
1.1 虚拟地址空间
程序将内存视为一个大数组,数组元素由单个字节组成,每个字节都由一个唯一的数字来表示,称为地址,所有地址的集合称为虚拟地址空间。
1.2 字节(Byte)和比特(bit)
- 1 Byte = 8 bit
- 二进制范围 00000000 ~ 11111111 => 十进制范围 0 ~ 255 (2^8-1)
1.3 字数据大小
字长决定了虚拟地址空间的最大范围(字长 w,虚拟地址范围 0 ~ 2^w - 1)
区别:32 位程序 & 64位程序
- 代码上:基本数据类型占用的字节长度不同(long、unsigned long、指针: 4bit -> 8bit)
- 可执行文件上:Class属性标识 ELF32 -> ELF64
1.4 寻址和字节顺序
举个例子:
int 类型变量 x(0x01234567),假设地址位于 0x100 处:
- 大端法(最高有效字节存储在最前面 - IBM 和 Sun 公司机器):
- 小端法(最低有效字节存储在最前面 - Intel兼容机、Android 和 iOS 系统)
- 双端法(ARM处理器)
1.5 C语言中的位级运算
如何得到操作数的最低有效字节?
&0xFF
2. 整数表示与编码
2.1 数值信息的表示
真值:带有正、负号的二进制数。例如+1010110、-0110101
机器数:用0 和 1 表示正负号的数(0正,1 负)。
常用的机器数编码方法有原码、反码和补
码
1)原码(正数符号位用0,负数用1)
0的原码不唯一 ([+0]原=00000000、[-0]原=10000000)
为了简化运算器复杂性,提高运算速度,要把减法做成加法运算,因此引入了反码和补码
2)反码
- 正数的反码与原码相同;
- 负数的反码是在原码的基础上符号位不变,其余各位按位求反得到的。
例子:
- X=+1010110, [X]反=[X]原=01010110
- Y=-0110101, [Y]原=10110101 [Y]反=11001010
- 0 无正负之分([+0]补=[-0]补=00000000)
3)补码(有符号整数常用补码存储)
- 正数的补码与原码相同;
- 负数的补码是在原码的基础上符号位不变,其它位按位取反后,+1(反码 + 1)
- 补码的补码是原码,即 [[X]补]补=[X]
- 验证补码的小技巧:[-5]补=1011,最高位1不仅是负号,也是8 => -8 + 2 + 1 = -5
- 例子:
- X=+1010110 [X]补=[X]反=[X]原=01010110
- Y=-0110101 [Y]原=10110101 [Y]补=11001011.
问:8位二进制的补码范围?
-128 ~ 127 (因为正数原码多涵盖了0)
正数原码:0000 0000(0) ~ 0111 1111(127)
负数原码:1000 0000 ~ 1111 1111(-127)
负数补码:1000 0000(-128) ~ 1000 0001(127)
2.2 有符号数和无符号数转换
C 语言会隐式的将有符号数强制转换成无符号数来执行运算
有符号数从一个较小的数据类型转换成较大类型时,进行符号位扩展,可保持数值不变
3. 整数运算
无符号加法 - 溢出判断sum < x
有符号加法 - 正溢出、负溢出
4. 浮点数
4.1 含有小数值的二进制数
- 定点表示法
- IEEE 浮点表示(可有效地表示很大的数)
符号 s、阶码 E 和尾数 M
4.2 浮点数的数值分类(根据阶码E)
1)规格化的值
阶码字段的二进制位不全为 0,且不全为 1
2)非规格化的值
阶码字段的二进制位全为 0
3)特殊值
当阶码字段的二进制位全为 1
4.3 舍入
当值x无法用浮点形式精确表示时,想找“最接近的值”来代替它
1)向下舍入和向上舍入
2)向零舍入
正数向下舍入,负数向上舍入
3)向偶数舍入(向最接近的值进行舍入)
使得一半情况需向上舍入,一半情况需向下舍入
4.4 浮点运算
- 浮点数的加法不具有结合性
- 浮点数的乘法不具有结合性
- 浮点数的乘法在加法上不具有分配性
5. 参考资料
https://github.com/datawhalechina/team-learning-program/tree/master/ComputerSystems