Skip to content

运算

思维导图

运算

补码

符号部分同原码

  • 数的最高位为符号位,0 表示正数,1 表示负数

数字部分与它的符号位有关

  • 对于正数,补码数值部分与原码数值部分相同

  • 对于负数,补码数值部分是将原码数值部分按位取反再加 1 ,即在反码数值部分基础上加 1

阶码

补码和移码的关系:符号位相反、数值位相同

  • 阶码用移码表示,阶码加减运算后得到补码,再将符号位取反即可得到运算后的阶码

  • 移码的和、差 = 真值的和、差的补码

补码 E_1 的(mod 2^n) n 位移码:

[E_1]移 = 2^(n-1) + E_1

补码 E_1 的(mod 2^n) n 位补码:

[E_1]补 = 2^n + E_1

浮点数(IEEE754 标准)

单精度浮点数

  • 31:1 位符号位

  • 30~23:8 位阶码

  • 22~0:23 位尾数

双精度浮点数

  • 63:1 位符号位

  • 62~52:11 位阶码

  • 51~0:52 位尾数

阶码全部为 0:

  • 尾数不为 0:表示非规格化数

  • 尾数为 0:表示数字 0

阶码全部为 1:

  • 尾数不为 0:NaN(非数)

  • 尾数为 0:

  • 符号位为 0:表示正无穷

  • 符号位为 1:表示负无穷

状态标志位

CF——进位标志位

  • 加法

  • 减法

OF——溢出标志位

ZF

计算机运算部件(ALU)的硬件组织

1 位全加器 / 普通进位加法器 CPA

存储进位加法器 CSA

  • n 位串行加法器 分 n 步实现,每步只求一位和

  • 进位按串行方式传递,速度慢

  • 进位延时较长,关键路径延时 O(n)
  • 实现复杂度 O(n)

  • n 位并行加法器

  • 同时产生进位

  • 加法延时缩短,关键路径延时 O(log n)

  • 实现相对复杂,复杂度 O(n2)

  • 完全大规模并行进位实现困难,因为高位的进位形成逻辑涉及输入变量过多,将受到器件扇入系数的限制

  • 分组并行进位加法器

  • 组内并行,组间串行

快速乘法器

  • 柱形乘法器

  • 阵列乘法器

快速除法器

  • 阵列除法器

定点整数阶码运算器和定点小数尾数运算器组成浮点运算器

与其他寄存器组构成完整的运算部件(ALU)

移位

算术左移

逻辑左移

算术右移

逻辑右移

注意易错

  • 对于整数,左移指令相当于将原数与 2 的幂次方相乘;右移指令则相当于将原来的整数除以 2 的幂次方。正数没啥问题,负数不行!

位扩展

短数转为长数

0 扩展:无符号数,即:前面补“0”,

符号扩展:有符号整数,即:前面补“数符

应用

  • 强制类型转换

  • 无符号数加入寄存器时用这种方式填补寄存器左侧多余位置

位截断

长数转为短数

强行将一个长数的高位丢弃

可能会发生数据“溢出”或者数据不正确

数据语义上的高位截断,与大小端存储方式无关

应用

  • 强制类型转换

  • 有符号数加入寄存器时用这种方式填补寄存器左侧多余位置

加减法

有符号原码加减法

符号位和数值部分分别处理 减法转化为加法处理

  • 同号:

  • 数值位直接相加

  • 和的符号取被加数的符号

  • 若最高位产生进位,则结果溢出

  • 异号:负数取补码,与正数相加,分二种情况讨论:

  • 最高数值位产生进位,符号位为 0,表明加法结果为正,所得数值位正确。

  • 最高数值位没有产生进位,符号位为 1,表明加法结果为负,得到的是数值位的补码形式,需对结果求补,得到原码结果

无符号原码加减法

补码加减法

补码可以化简加法运算 还可以将减法运算转化为加法运算

  • 溢出 同符号数相加或异符号数相减才可能溢出

  • 补码中采用两位符号位(变形补码),符号位仍然参与运算,结果中的两位符号位标示溢出状态

    • 11、00:正常

    • 01:正溢出

    • 10:负溢出

  • C 语言不考虑溢出的异常处理

    • 对于 unsigned 整型溢出:做模运算

    • 对于 signed 整型的溢出,C 的规范定义是“undefined behavior”

  • MIPS:

    • MIPS 上的 C 编译器会选用无符号的算术运算指令(如 addu、addiu、subu)

    • MIPS 上的 Fortran 编译器则会根据操作数的不同类型选用合适的算术运算指令(如 add、addi、sub)

    • MIPS 检测到有符号数运算溢出时,产生一个异常(exception/interrupt)

    • 造成溢出的那条指令的地址被存放在一个特定寄存器——异常程序计数器(EPC)

    • mfc0 指令将 EPC 中的地址复制到某个寄存器(k0/k1),用 jr 指令返回到溢出而中断的代码处

移码加减法

  • ① 加法:直接将[E1]移 和 [E2]移进行模 2n 相加,对结果符号取反得到结果的阶码

  • ② 减法:先将减数[E2]移 求补(各位取反,末位加 1),再与被减数 [E1]移进行模 2n 相加,对结果的符号取反

  • ③ 溢出判断:进行模 2n 相加时,如果两个加数的符号相同,且与和数的符号也相同,则发生溢出

乘法

“加” + “右移”

原码一位乘法

  • 符号位和数值位分开运算,数值部分用无符号数乘法实现

  • 用于浮点数尾数乘法运算

补码乘法

  • 用于定点整数乘法法运算

  • 现在主流乘法器是 3 位乘法,甚至 4 位,都是基于两位判断位

  • Booth 一位乘法

  • 被乘数 A 和部分积 P 均取两位符号位即变形码,乘数取一位符号位,符号位参与运算

  • 乘数末尾增设附加位 Bn+1 ,其初始值为 0

  • Bn 和 Bn+1 构成各步运算的乘数判断位

  • 按补码移位规则:部分积为正(第 1 符号位为 0),右移时有效位最高位补 0;部分积为负,右移时有效位最高位补 1

  • 按 Booth 乘法表算法进行到第 n+1 步,但第 n+1 步的部分积不再移位

  • Booth 二位乘法

  • 两位两位看,从右往左看,但每次[A]补的“数量级”不一样

  • (-1)X(-1)是定点小数补码乘法唯一溢出情况

使用伪加器构成柱形乘法器

  • 三个数的求和由两次普通加法变成了:一次伪加,一次普通加

  • 四个数的求和,通过两次伪加,一次普通加

  • 求和加的数越多,普通加仍是一次,伪加增多,伪加器相比全加器效率更高

利用实现多位乘的专用芯片构成阵列乘法器

除法

“加/减”+“左移”

原码除法

  • 符号位和数值位分开,数值部分用无符号数除法实现

  • 用于浮点数尾数除法运算

  • 有恢复余数和加减交替法两种

补码除法

  • 符号位和数值位一起运算

  • 用于定点整数除法运算

快速除法器:阵列除法器

浮点数加减法

求阶差

对阶

尾数相加减

规格化并判断溢出

  • 尾数规格化范围:1 ≤ 尾数真值 < 2

  • 阶码不溢出的范围:127 ≥ 阶码真值 ≥ -126

  • 阶码上溢:结果发生溢出,一般将其认为是+ ∞ 和-∞

  • 阶码下溢:结果为 0

  • 尾数上溢:

  • 不一定浮点数溢出,即不一定会发生“异常”

  • 右归:将尾数右移,阶码增 1 来重新对齐

  • 尾数下溢:

  • 进行舍入处理

  • 在运算过程中,添加保护位

舍入

  • 就近舍入,舍入为最近可表示的数

  • 附加位为:

  • 11:入

  • 01:舍

  • 10(强制结果为偶数)

  • 00:保持结果不变

置 0

  • 尾数为 0 说明结果也为 0,根据 IEEE754,阶码和尾数全为 0,需要将阶码置零

注意易错

  • 浮点数加减法不满足结合律

浮点数乘除法

尾数用定点原码乘/除运算实现

阶码用定点数加/减运算实现

规格化

  • 乘法

  • 1≤ 尾数 1 × 尾数 2<4

  • 不需左规、最多右规(➗2)一次

  • 除法

  • 0.5<尾数 1 ÷ 尾数 2<2

  • 不需右规、最多左规(✖️2)一次

符号确定

  • 同号:结果为正

  • 异号:结果为负