定点运算和浮点运算


定点运算

移位运算

计算机中的小数点的位置是事先约定的,因此二进制表示的机器数在相对于小数点做n位的左移或右移时,实质是使该数乘以或除以2^n

算数移位的规则

注意:这里的移位填补代码只是在数值位的范围之内,无论如何移位,符号位是不变的

要注意区分与逻辑移位的区别,算数移位只移动数值位,符号位不变,逻辑移位所有位一起移动,相当于无符号数的移位

加减法运算

补码加减法运算公式

补码加法运算公式

  • 整数 [A] + [B] = [A + B] (mod 2n+1)
  • 小数 [A] + [B] = [A + B] (mod 2)

补码表示的两个数进行加法运算时,可以把符号位与数位进行同等处理,只要结果不超出机器能表示的数值范围,运算后的结果进行取模操作,就能得到运算结果。

根据加法运算公式可以很容易的得到减法运算公式:

  • 整数 [A - B] = [A] + [ -B] (mod 2n+1)
  • 小数 [A - B] = [A] + [ -B] (mod 2)

这样就将减法运算转化为了加法运算,[-B]由[B]连同符号位在内,每位取反,末位加一取得。

溢出判断

一位符号位判断溢出

参加操作的两个数(减法即为被减数和“求补”以后的减数)符号相同,其结果的符号与原操作数的符号不同,即为溢出。

硬件实现

最高有效位的进位与符号位的进位进行异或,结果为1,即溢出

两位符号位判断溢出

含有两位符号位的补码,称为变形补码,它是以4为模的,定义为:

[x]补‘ = x (1 > x >= 0) 或 [x]补‘ = 4 + x (0 > x >= -1)(mod 4)

在用不行补码做加法时,两位符号位要连同数值部分一起参加运算,而且高位符号位产生的进位自动丢失。

[x]补‘ + [y]补‘ = [x + y]补‘ (mod 4)

[x - y]补‘ = [x]补‘ + [-y]补‘ (mode 4)

判断溢出的原则是:结果的两位符号位不同时,表示溢出,否则,无溢出。无论是否发生溢出,高位的符号位代表真正的符号。

乘法运算

笔算乘法

举例:A = -0.1101, B = 0.1011,笔算列竖式可求得结果:

分析笔算过程:

  • 符号位单独处理
  • 乘数的某一位决定是否加被乘数
  • 4个位积一起相加
  • 乘积的位数扩大一倍

笔算乘法的改进

可见,两个数的乘法运算可以视为加法和移位(乘2-1相当于做一位右移)两种运算,计算机比较容易实现

改进后的竖式运算过程:

总结上面的运算过程:

  • 乘法运算可用加法和移位实现,两个四位数相乘,需要四次加法和四次移位
  • 由乘数的末尾决定被乘数是否与原部分积相加,然后右移一位形成新的部分积,同时乘数也右移一位,末位丢弃,空出的高位存放部分积的低位
  • 被乘数只与部分积的高位相加

由上面过程可得,计算机要实现这样的乘法,硬件方面需要3个寄存器,其中两个要具有移位功能

原码乘法

  • 原码一位乘

原码与真值只差一个符号,乘积的符号恶意通过符号位异或求得,数值部分可直接采用上述的乘法过程

运算规则:

设[x] = x0.x1x2…xn,[y] = y0.y1y2…yn

则[x * y] = x0(XOR)y0.(0.x1x2…xn)(0.y1y2…yn)

式中0.x1x2…xn为x的绝对值,0.y1y2…yn为y的绝对值

特点:

  • 绝对值运算
  • 用移位的次数判断乘法是否结束
  • 逻辑移位

除法运算

笔算除法

举例:A = -0.1011, B = 0.1101,笔算列竖式可求得结果

分析笔算过程:

  • 商符单独处理
  • 心算上商
  • 余数不动低位补0,减右移一位的除数
  • 上商位置不确定

笔算除法与机器除法比较

笔算除法 机器除法
商符单独处理 符号位异或
心算上商 比较被除数与除数绝对值的大小确定商值
余数不动低位补0,减右移一位的除数 余数左移一位低位补0减除数
2倍字长加法器 1倍字长加法器
上商位置不固定 在寄存器的最末尾上商

原码除法

以小数为例:

设[x] = x0.x1x2…xn,[y] = y0.y1y2…yn

则[x / y] = x0(XOR)y0.(0.x1x2…xn)/(0.y1y2…yn)

式中0.x1x2…xn为x的绝对值,用x*表示,0.y1y2…yn为y的绝对值,用y*表示。

约定

  • 小数定点除法中 x* < y*
  • 整数定点除法中x* > y*
  • 被除数不为0
  • 除数不为0

原码除法中由于对余数的处理不同,由可分为恢复余数法和加减交替法

恢复余数法

恢复余数法的特点是:当余数为负时,需要加上除数,将其恢复为原来的余数

例:x = -0.1011 y = -0.1101,求[x/y]

[x] = 1.1011 [y] = 1.1101 [y*] = 0.1101 [-y*] = 1.0011

数值部分的运算过程如下:

符号位:1(XOR)1 = 0

所以[x/y] = 0.1101

整个运算过程中,上商5次,第一次上商判断溢出;余数为正时,上商1,余数为负时,上商0,恢复余数

加减交替法

这种方法是恢复余数法的一种改进算法

分析恢复余数法可知:

  • 余数R>0时,可上商“1”,再对R左移一位后减余数,即2R - y*
  • 余数R<0时,可上商“0”,然后先做R + y*,即完成恢复余数的运算,再做2(R + y*) - y*,即2R + y*

对恢复余数法进行归纳:

  • 余数R>0时,可上商“1”,做2R - y*运算
  • 余数R<0时,可上商“0”,做2R + y*运算

没有了恢复余数,只有加减操作,因此称为加减交替法

例:x = -0.1011 y = -0.1101,求[x/y]

[x] = 1.1011 [y] = 1.1101 [y*] = 0.1101 [-y*] = 1.0011

数值部分的运算过程如下:

符号位:1(XOR)1 = 0

所以[x/y] = 0.1101

上述过程的特点为:

  • 上商 n+1 次
  • 第一次上商判断溢出
  • 移位n次,加 n+1 次
  • 用移位的次数判断除法是否结束

浮点四则运算

浮点加减运算

设两个浮点数x = Sx* 2jx ,y = Sy* 2jy

浮点数尾数的小数点固定在第一数值位之前,因此可以直接采用定点数的运算规则,但前提是两个浮点数的阶码相同

浮点数加减法的运算步骤:

  • 对阶,使两数的小数点位置对齐
  • 尾数求和,按顶点数加减运算规则求和
  • 规格化
  • 舍入,为提高精度,要考虑位数右移时丢失的数值位
  • 判断结果,是否溢出

对阶

首先要求出阶差,再按小阶向大阶看齐的原则,使阶小的尾数向右移,每移一位,阶码+1,直到两数的阶码相等,右移的次数正好等于阶差

为何小阶向大阶看齐?

如果反过来的话,大阶向小阶看齐,阶码要减1,尾数要左移,那么尾数最高位的数值位就会被丢弃,移位后得到的结果是错误的,而尾数右移的话只会影响数的精度

规格化

规格化数的定义:

1/2 <= |S| < 1 r = 2

规格化数的判断:

  • S > 0 时,其原码格式为0.1xx…x,补码格式为0.1xx…x,反码格式为0.1xx…x
  • S < 0 时,其原码格式为1.1xx…x,补码格式为1.0xx…x,反码格式为1.0xx…x

因此,原码格式时,第一数值位为1即为规格化数;补码格式时,符号位和第一数值位不同时,即为规格化数

但有两个特例:

  • S= - 1/2时,[S]= 1.100…0,[S]= 1.100…0,因此[-1/2]不是规格化数
  • S= - 1时,[S]= 1.000…0,因此[-1]是规格化数

规格化可分为左规和右规

  • 当尾数出现00.0xx…x或11.1xx…x时,需要左规,尾数左移一位,阶码减1,知道数符和第一数值位不同
  • 当尾数出现01.xxx…x或10.xxx…x时,表示尾数溢出,需要右规,右规时尾数右移一位,阶码加1

舍入

在对阶和右规的过程中,可能出现尾数末尾丢失的情况,引起误差,需要考虑舍入,提高尾数的精度

  • 0舍1入法:如果被移去的最高数值位是0,则舍去,是1,则尾数末位加1,此时需再右规一次判断是否再次溢出
  • 恒置“1”法:不管被移去的最高数值位是1还是0,都使右移后的尾数末位恒置1

溢出判断

设机器数为补码,尾数为规格化形式,并假设阶符取2位,阶码取7位,数符取2位,尾数取n位,则该补码在数轴上的表示范围为:

如图可以发现,当阶码大于127时,发生上溢,机器停止运算做溢出判断处理;当阶码小于-128时,发生下溢,浮点数值趋于零,机器不做溢出处理,仅把它作为机器零。

浮点机的溢出与否可由阶码的符号决定,即:

  • 阶码[j] = 01,xx…x为上溢
  • 阶码[j] = 10,xx…x为下溢,按机器零处理

文章作者: likai
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 likai !
评论
 上一篇
python数据结构之栈 python数据结构之栈
概念栈是线性数据结构的一种,是数据项的有序集合。添加项和移除项都发生在同一端,称为“顶端”,另一端称为“底端”。 因为添加项和移除项都在栈的顶端进行,因此最新添加的项在移除时也会被第一个移除,这种排序原则称为后进先出(LIFO),这意味着越
2020-07-24
下一篇 
  目录