浮点数运算

      今天学习了浮点数运算(加减乘除)。浮点数运算主要包括两部分:指数运算和尾数运算。在IEEE754标准下,指数运算就是阶码的运算,类似于无符号数运算。尾数运算是原码运算。之前一直很疑惑为什么前面的教材在介绍原码运算(加减乘除)所举的例子都是小数运算。现在猜想那部分内容可能只是为了浮点数运算做铺垫,这里才是主要的内容。(当然知识是不分重点的,但考试分)。下面就来详细介绍下浮点数运算的过程吧!另外本文使用的浮点数标准均为IEEE754结构,即单精度数由1位符号位,8位指数位,23位尾数位共计32位组成。

一、浮点数的加减运算:

       浮点数的加减运算分为5个步骤:对阶、尾数相加、尾数规格化、尾数舍入处理、溢出判断处理。下面详细介绍:

1. 对阶:

      所谓对阶,就是让两个操作数阶数相同,以便进行加减。实现的方式是对较小数的尾数进行右移操作。对阶的原则是向高阶看齐。计算公式为:
在这里插入图片描述
      当结果大于0说明被加数(被减数)阶数高,则对加数(减数)进行移位对阶。小于0则反之改变被加数(被减数)。

2. 尾数加减:

      将两个操作数的尾数相加减。值得注意的是:在IEEE754标准中,对于规格化数来说在小数点前有一位隐藏位1,在加减过程中需要把它还原到尾数中。尾数加减的实质是原码的加减,对于原码加减的规则如下图所示:

在这里插入图片描述

3. 尾数规格化:

      加减完成的尾数形式未必满足IEEE754对于尾数的要求,即保留23位,小数点在第一个1之后。需要对尾数进行左规和右规,下面介绍一下左规和右规。

      左规:将尾数向左移,用于清除第一个1前面出现的0。左规伴随着阶码减少,在左规过程中要检测阶码是否发生下溢,即阶码达到最小值(0000 0000)。

      右规:将尾数向右移,用于两数相加后出现向高位进位的情况。因为两数相加最多进一位,所以右规最多一位。右规伴随着阶码的增加,在右规过程中要检测阶码是否发生上溢,即阶码达到最大值(1111 1111)。

4. 尾数的舍入处理:

      在对阶和右规的时候,最右边的数字会被移出。为了保证最后计算的精度,把这些数字在过程中保存,等到最后进行舍入。也就是我上文提到的附加位。有两个问题值得注意:

      1) 保留多少附加位合适?

      2)最终对附加位怎么进行舍入?

      在IEEE754中保留了保护位,舍入位,粘位三位作为附加位。同时对于IEEE754来说最后附加位的舍入,有如下规则:
在这里插入图片描述

5. 溢出判断:

      在浮点数中是以阶码的溢出与否来作为评判标准的。单精度溢出分为上溢(指数大于等于127)和下溢(指数小于等于-126)。

      插一句:“之前一直以为下溢的指数是-149,这个数字来源于-126再把所有的尾数向右移,当到达-149时刚刚好所有尾数全部为零,即表示零。这个误区在于没有正确的区分规格化数和非规格化数。对于规格化数而言,下溢就是-126,所以规格化数表示的最小值为1.00…乘2的-126次方,而0~0.111…乘2的-126次方就是非规格化数表示的范围。-149正是非规格化数表示的最小范围。这里贴一张图,更加便于理解。

在这里插入图片描述
      下面直接粘贴一个书上的实例,对以上过程进一步加深了解:
在这里插入图片描述

二、浮点数乘除运算:

      浮点数乘除和定点数乘除相同,在正式运算前会对操作数进行预处理。对于乘法如果有一个操作数为0则结果为0。对于浮点数除法,若被除数为0,则结果为0。除数为0分两种情况,第一种是被除数非零,第二种是被除数为0。下面着重介绍一下两种除数为0:
      除数为0,被除数不为0:
         结果为无穷大。在IEEE 754标准下就是阶码全为1,尾数全为0。C语言输出如下图:
在这里插入图片描述
      除数为0,被除数为0:
         结果是NAN(not a number)。在IEEE 754标准下就是阶码全为1,尾数非0。在C语言中输出如下图:
在这里插入图片描述
      注:在Windows系统下,-1.#IND00即代表nan,Linux系统下会输出nan。

      下面详细介绍无特殊情况浮点数的乘除运算:

      浮点数乘除运算公式如下图:
在这里插入图片描述

   1.浮点数的乘法:

         点数的乘法运算主要分为四步:尾数相乘指数相加、尾数规格化、尾数舍入处理、溢出处理判断。

       1)尾数相乘,指数相加:

         尾数相乘即为原码相乘,这个具体的过程请参考另一篇文章:定点数运算(于文末给出网址)值得注意的是,对于规格化浮点数要记得恢复隐藏位。指数相加可以直接运用移码的计算方法:

      2)尾数规格化:

         对于两个操作数的尾数一定都是大于1的(隐藏位导致),所以最终得到的结果,小数点前会有两位共三种情况(01,11,10)。若为01则不需规格化,11和10则需右规一位。注意对于IEEE754标准浮点数乘法不需要左规。

      3)尾数舍入处理:

         两个小数相乘,尾数自然更多,但位置是有限的,需要对尾数进行舍入,具体的舍入规则参照浮点数加减的舍入规则即可。

      4)溢出处理判断:

         乘法的溢出有两种可能:阶码相加减时,以及尾数右规时。右规与上文相同,下面介绍一下阶码溢出的判断标准:
在这里插入图片描述
      注:Eb是最终的结果,EX和EY是操作数的指数值。

   2.浮点数除法:

      浮点数除法大致分为4步:尾数相除阶相减、尾数规格化、尾数舍入、溢出判断处理。由于除法大部分与乘法相似,所以此处只列出不同部分。

     在尾数相除阶相减过程中,尾数除法也在上文引用那篇文章中有具体介绍。阶码相减的运算公式如下:
在这里插入图片描述
      在尾数规格化步骤中:当除法运算完成后,若小数点前为0,则需进行左规以保证小数点前具有隐藏位1。

      对于除法阶码溢出判断的规则如下:
在这里插入图片描述
      注:Eb为最终结果指数,EXEY为操作数指数。

补充:在《程序是怎样跑起来的?》书中,对于阶码为什么使用0-127做了一个原因的解释:在计算机中,使用EXCESS系统的方法来同时存储正数和负数。这里面的0-127就是增加幻数之后的数字。幻数选择了127,可记为Excess_127。

本篇文章对于浮点数运算进行了介绍,因为作者水平有限,可能某些地方理解错误,请高手不吝赐教,批评指正,谢谢!
  • 17
    点赞
  • 132
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
Verilog是一种硬件描述语言,主要用于描述数字电路和系统。它通常用于设计和模拟数字电路,而不是用于浮点数运算。在Verilog中,浮点数运算并不是直接支持的,因为Verilog主要用于处理整数和逻辑运算。 如果需要进行浮点数运算,可以使用其他编程语言,如C或Python,来实现。这些语言提供了丰富的浮点数运算库和函数,可以方便地进行浮点数运算。 在Verilog中,如果需要进行类似浮点数的运算,可以使用固定点数表示法来近似实现。固定点数表示法是一种将浮点数转换为整数进行运算的方法。通过将小数部分乘以一个固定的倍数,并将结果转换为整数,可以实现近似的浮点数运算。 以下是一个使用固定点数表示法进行加法运算的Verilog代码示例: ```verilog module fixed_point_addition ( input [7:0] a, input [7:0] b, output [7:0] sum ); reg [15:0] a_fixed; reg [15:0] b_fixed; reg [15:0] sum_fixed; // 将小数部分乘以256,转换为整数 assign a_fixed = a * 256; assign b_fixed = b * 256; // 进行整数加法运算 always @* begin sum_fixed = a_fixed + b_fixed; end // 将结果除以256,恢复为浮点数 assign sum = sum_fixed / 256; endmodule ``` 请注意,这只是一个简单的示例,用于说明如何使用固定点数表示法进行近似的浮点数运算。实际上,浮点数运算涉及更复杂的算法和技术,需要使用更高级的工具和库来实现。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值