本文最后更新于3 年前,文中所描述的信息可能已发生改变。
2020-2021-2 计算机系统
2020-2021学年第二学期 计算机系统
基于32位系统
随上课进度更新
位、字节与信息存储
机器字长
指明整数和指针数据标称大小
位级操作
- 一个内存地址存放的是一个字节(8个bit);
- 地址指明的是某个字节的存放位置;
- 即某数据第一个字节所在位置;
- 因此连续存放的两个字之间相隔4个地址(32位字长)或8个地址(64位字长)。
大小端
举例:
$0x1234
地址 | 大端 | 小端 |
---|---|---|
00 | 12 | 34 |
01 | 34 | 12 |
(小端:高地址、高有效位在后面)
位移
左移:x << y
将x左移y位,在右边填0。
右移:x >> y
逻辑移位:补0
算术移位:填充符号位
整数
整形数据取值范围
不详细记录。
整数编码
假设一个整型数据有w位,用位向量的形式表示这个数的二进制。
无符号数
每个介于0 ~ 2^w - 1之间的数都有唯一一个的w位的编码。
补码
最高有效位是符号位。
(函数表示待补)
例:
B2T 4 ([0001]) = -0 * 2^3 + 0 * 2^2 + 0 * 2^1 + 1 * 2^0 = 0 + 0 + 0 + 1 = 1
B2T 4 ([0101]) = -0 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 0 + 4 + 0 + 1 = 5
B2T 4 ([1011]) = -1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 1 * 2^0 = -8 + 0 + 2 + 1 = -5
B2T 4 ([1111]) = -1 * 2^3 + 1 * 2^2 + 1 * 2^1 + 1 * 2^0 = -8 + 4 + 2 + 1 = -1
显然,补码的范围是不对称的,|Tmin| = |Tmax| + 1。
补码、补码值盒子
整数表示
求补码的其他方法?
C语言中的整数
- 常数
- 默认是有符号数;
- U作为无符号数的后缀,如0U,1234U。
- 转换
- 用(类型)来转换,位模式不变,按转换后的类型重新解释;
- 也可以通过赋值语句和过程调用来实现。
特殊情况
- 表达式
- 如果一个表达式中同时出现有符号数和无符号数,有符号数直接转成无符号数;
- 上述表达式包括比较运算:<,>,==,<=,>=。
例:w = 32,Tmin = -2147483648,Tmax = 2147483647
常数1 | 常数2 | 关系 | 结果 |
---|---|---|---|
0 | 0U | == | 1 |
-1 | 0 | < | 1 |
-1 | 0U | < | 0 |
2147483647 | -2147483647-1 | > | 1 |
2147483647U | -2147483647-1 | > | 0 |
-1 | -2 | > | 1 |
(unsigned) -1 | -2 | > | 1 |
2147483647 | 2147483648U | < | 1 |
2147483647 | (int) 2147483648U | < | 0 |
整数的扩展与截断
符号位扩展
- 将w位的有符号数x转换为(w+k)-bit的整数,保持值不变。
- 参考算术移位,符号位是几就在高位补充几。
截断(例如从无符号整型变成无符号短整型)
- 对于无符号数就是mod操作
- 对于有符号数,类似于mod,剩下的以补码解释。
例:
int x = 53191;
short sx = (short)x; //-12345
加法
无符号数加法
忽略最高进位。
通过取模来实现。
补码加法
舍弃最高位,按补码解释。
- 若sum >= 2^(w-1),补码结果为负数,为正溢出,导致结果减少;
- 若sum <= -2^(w-1),补码结果为正数,为负溢出,导致结果增加。
乘除法
乘法
乘积有2w位,忽略乘积的高w位;
用移位代替乘法:左移乘,右移除;
除法
除数为无符号数时使用逻辑右移;
除数为有符号数时使用算术右移;
除法的修正
- 加偏置值
浮点数
- 二进制小数点右侧的“位”表示2的分数幂(负幂);
- 其他值只能近似表示。
例:0.101(2) = 0.5 + 0.125 = 0.625。
IEEE浮点数
- 数学形式:(-1)^s M 2^E
- 符号位s,确定这个数是正数还是负数,数值0的符号位特殊处理;
- 尾数M是一个二进制小数,通常规定在范围1 ~ 2-ε或0 ~ 1-ε;
- 阶码E表示2的幂。
精度 | s(符号) | exp(阶码) | frac(尾数) |
---|---|---|---|
单精度32-bits | 1 | 8-bits | 23-bits |
双精度64-bits | 1 | 11-bits | 52-bits |
扩展精度80-bits | 1 | 15-bits | 63 or 64-bits |
浮点数的三种情况
规格化的值
当exp的位模式既不全为0,也不全为1时都属于这种情况;
阶码字段被解释为以偏置形式表示的有符号整数,阶码的值E = e - Bias,其中e是无符号数其位表示为e(k-1)…e(1)e(0),而Bias是一个等于2^k-1 - 1的偏置值;
小数字段frac被解释为描述小数值f,其中0 <= f < 1。
例:
float F = 15213.0;
15213(10) = 11101101101101(2) = 1.1101101101101(2) * 2^13;
- 尾数
- M = 1.1101101101101(2);
- frac = 11011011011010000000000(2);
- 阶码
- E = 13;
- Bias = 127;
- Exp = 140 = 10001100(2);
- 结果
- 0 10001100 11011011011010000000000
- 尾数
非规格化的值
当阶码域全为0时,所表示的数就是非规格化形式。在这种情况下,阶码值是E = 1 - Bias,而尾数的值是M = f,也就是小数字段的值,不包含隐含的开头的1。
- 例:
- exp = 000…0,frac = 000…0,此时值为0,符号位决定“+0”或“-0”;
- exp = 000…0,frac != 000…0,此时为非常接近0.0的数。
- 例:
特殊值
当阶码全为1的时候出现。
- 情况1:
- exp = 111…1,frac = 000…0,表示的是无穷大,由符号位决定正负;
- exp = 111…1,frac != 000…0,表示的不是一个数(NaN),用来表示一些无法表示的数,如sqrt(-1)等,在某些应用中也可用来表示未初始化的数据。
- 情况1:
舍入
四种舍入方式示例:
方式 | 1.40 | 1.60 | 1.50 | 2.50 | -1.50 |
---|---|---|---|---|---|
向偶数舍入 | 1 | 2 | 2 | 2 | -2 |
向零舍入 | 1 | 1 | 1 | 2 | -1 |
向下舍入 | 1 | 1 | 1 | 2 | -2 |
向上舍入 | 2 | 2 | 2 | 3 | -1 |
向偶数舍入能找到最近的匹配值,其他三种用于计算上界和下界。
向偶数舍入也可以舍入到其他数位:
- 中间值舍入到偶数;
- 例如,舍入到百分位:
- 1.2349999 -> 1.23;
- 1.2350001 -> 1.24;
- 1.2350000 -> 1.24;
- 1.2450000 -> 1.24。
向偶数舍入法能够运用于二进制小数。
- 将最低有效位的值0认为是偶数,值1认为是奇数;
- “中间值”是指舍入位的右边正好是**100…(2)**的形式;
- 例如,舍入到1/4(小数点右边两位):
- 2 3/32,即10.00011(2),小于中间值,结果为10.00(2),即2
- 2 3/16,即10.00110(2),大于中间值,结果为10.01(2),即2 1/4
- 2 7/8,即10.11100(2),等于中间值,结果为11.00(2),即3
- 2 5/8,即10.10100(2),等于中间值,结果为10.10(2),即2 1/2
浮点运算
浮点数加法
- 对阶,小阶向大阶对齐
- 两数的阶码不同,表示小数点的位置没有对齐;
- 将原来阶码小的数的尾数右移|ΔE|位,其阶码值加上|ΔE|,即每右移一次尾数要使阶码加1,则该浮点数的值不变(但精度变差了);
- 尾数进行加法运算
- 结果规格化并进行舍入处理
- 如果尾数不是规格化数,需要进行规格化处理,并进行舍入;
- 判断溢出
- 根据阶码判断是否溢出。
浮点数加法的数学特性
- 与阿贝尔群比较
- 有交换性;
- 没有结合性(由于舍入);
- 3.14 + 1e10 - 1e10 = 0;
- 3.14 + (1e10 - 1e10) = 3.14;
- 单调性
- 如果a >= b,对于任何a、b以及x的值,除了NaN和无穷大,都有x + a >= x + b,而无符号数加法或补码加法不具有这个实数、整数加法的属性。
浮点数乘法
(-1)^s1 M1 2^E1 * (-1)^s2 M2 2^E2
- 精确结果:(-1)^s M 2^E
- 符号位s:s1 ^ s2;
- 尾数M:M1 * M2;
- 阶码E:E1 + E2;
- 调整
- 如果M >= 2,M右移一位,E = E + 1;
- 如果E超出表示范围,溢出;
- 将M舍入到frac的位数范围。
浮点数乘法的数学特性
- 可交换性
- a * b = b * a;
- 不可结合性
- a * b * c != a * (b * c);
- 不具备分配性
- a * (b + c) != a * b + a * c;
- 单调性
- 若a >= b且c >= 0,则a * c >= b * c,(都不等于NaN或无穷大)。
C语言中的浮点数
float & double
- 转换
- double/float -> int
- 值向零舍入,对于无法表示或超出范围的值未定义;
- int -> double
- 能有效保留精确值;
- int -> float
- 数字不会溢出,可能会被舍入。
- double/float -> int