按:计算机组成课程第四周作业

算法证明

图表 1       浮点数的表示

浮点数的表示如上图所示,我们要做的是将按如上方式存储的两个浮点数相乘,将其结果用如上的方式表示。

符号位只是两者的异或,指数位基本上是两指数的相加,而尾数位就需要在正常的乘法之余考虑到移位(和随之而来的指数为的溢出)和进位的情况。

下面就来讨论一下尾数的运算:

在尾数前补上1,进行无符号数乘法。小数点仅作为算法分析时的记号,实际上不参加运算。用64位的long long类型的数来存储运算结果。

图表 2       尾数相乘(用“画图”程序画的)

如上图所示,后46个数字是结果的小数点后的数据,小数点的的问号处可能只有1,可能是1X(10或11,在算法中没有太大区别)。若问号处只有1,说明已经规格化完成;若是1X,需要将整个数右移一位,质数加一,从而使问号处只有1。

规格化后要进行round操作,如下图所示。如果第23位是0,这一位之前的23位就是所需要的尾数。如果第23位是1,截取这位之前的数,加一(类似于四舍五入)。判断结果是否仍规格化。若没有规格化,从规格化开始继续做,直到找到规格化后的23位尾数。

图表 3       有效数处理(用“画图”程序画的)

程序框图

主要流程如下图所示。在代码注释中的Step1到step5即分别对应流程图中的1至5部分。有所不同的是,因为后面只会增加exponent而不会减少,所以我的程序在step1就判断是否overflow,在step3也判断是否overflow就行了,规格化完成后再判断underflow。

图表 4       浮点乘法程序框图

使用方法

输入两个数,程序用自带的scanf将其作为单精度浮点数读入。通过一系列的无符号数的计算,得到用单精度浮点数表示的结果,将其输出(为了更详细地看到整个数,输出的数小数点后有20位)。如果overflow或underflow,输出的是相应的提示。为了验证计算是否正确,在输出的数据后面有个括号,里面放了是直接让机器进行的单精度浮点数的乘法的结果。

特殊处理

特殊输入数据

有些输入的数据是在太大或太小,以至于数据本身就已经overflow或underflow,从而根本无法存贮到单精度浮点数中,不是合法的单精度浮点数。对于这样的数,我们不应该对其提供任何服务,不然只会闹出笑话。

对于零要特殊处理,因为0在浮点数中的表示并不是按照一般的规范来的。

溢出

这里的溢出指的是乘数和被乘数本身是合法的单精度浮点数,但相乘后造成了溢出。

因为后面只会增加exponent而不会减少,所以与上面的流程图不同,我的程序在step1就判断是否overflow,在step3也判断是否overflow就行了,规格化完成后再判断underflow。

数位扩展

整个程序都是按照单精度的浮点数来写的,数位扩展可能有点麻烦。如果要扩展为双精度的,需要更改代码中的大量参数。鉴于浮点数一般也就只有单精度和双精度两种,我觉得不是太必要提高做成可扩展的。

实例分析

图表 5       大数的乘法

图表 6       overflow

图表 7       underflow(本程序判为underflow,而C语言自己的浮点数乘法计算结果为0.000000)

图表 8       对0的乘法

图表 9       很大的与很小的正数相乘

图表 10     观察精确度

图表 11     对负数乘法的测试

图表 12     对于无法用浮点数表示的输入数据

图表 13     对于过小的数据

结果分析

我们对过于大的数据和过于小的数据,以及精度太大的数据都做了试验。从上述结果可以看到,这个程序的结果与C程序自带的浮点数乘法结果基本吻合。说明这个程序还是比较可靠的。

通过对精度的测试,我们发现浮点数虽然能表示较大较小的数据,但有效数字还是有限的。如-100与0.6相乘的结果,整数部分60是对的,小数点五位后就出现了偏差。一连串8与1相乘,结果的头部只有7个8。可以大致地认为浮点数的表示与计算的十进制有效数位是7位。

可以更进一步的工作

l  程序中对于无符号整数的加法、乘法,对于exponent的有符号整数运算都是直接使用的,其实可以调用之前写的相关程序,做成更加本质的浮点数乘法。

Source Code

#include

union unionfloat{

float f;

unsigned long l;

};

union unionfloat x,y,product;

/*

disp(union unionfloat x)

{

long i;

unsigned long m;

printf("%f:",x.f);

m=0x80000000;

for(i=0; i<32; i++){

if((i&7)==0)printf(" ");

if(m&x.l)printf("1");

else printf("0");

m>>=1;

}

printf("\n");

}*/

int mul(void){

//Step 1

int exponent;

exponent=(x.l&0x7F800000)>>23;

exponent-=0x7F;

exponent+=(y.l&0x7F800000)>>23;

exponent-=0x7F;

if(exponent>=128) return 1;

//Step 2

unsigned long long raw_product;

unsigned long long raw_x=x.l&0x007FFFFF|0x00800000;

unsigned long long raw_y=y.l&0x007FFFFF|0x00800000;

int carry;

raw_product = raw_x * raw_y;

/*int i=64;

unsigned long long p=0x8000000000000000;

while(i--){

if(i%4==3)printf(" ");

if(raw_product&p)printf("1");

else printf("0");

p=p>>1;

}

printf("\n");*/

//相乘结果若小数点前有两位

do{

//Step 3

if(raw_product>>47){

raw_product = raw_product>>1;

exponent++;

if(exponent>=128) return 1;//printf("Overflow");

}

//Step 4

if(raw_product & 0x0000000000400000){

raw_product = ((raw_product>>23)+1)<<23;

}

}while(raw_product>>47);//still normalized?

//Step 5

product.l = ((x.l>>31)^(y.l>>31))<<31;

if(exponent<=-127)return -1;//printf("Underflow");

//-127

product.l = product.l | ((unsigned long)(exponent+127))<<23;

product.l = product.l|((unsigned long)((raw_product&0x00003FFFFF800000)>>23));

//disp(product);

printf("%.20f(%.20f)\n",product.f,x.f*y.f);

return 0;

}

int main(void){

while(~scanf("%f%f",&x.f,&y.f)){

//printf("Input %.10f %.10f\n",x.f,y.f);

//disp(x);disp(y);

if(x.l==0||y.l==0)

printf("%f(%f)\n",0,x.f*y.f);

else if((((x.l>>23)&0x000000FF)==0) || (((x.l>>23)&0x000000FF)==0x000000FF))

printf("The first number is unavailable\n");

else if((((y.l>>23)&0x000000FF)==0) || (((y.l>>23)&0x000000FF)==0x000000FF))

printf("The second number is unavailable\n");

else{

switch(mul()){

case 1:printf("Overflow(%f)\n",x.f*y.f);break;

case -1:printf("Underflow(%f)\n",x.f*y.f);break;

default:break;

}

}

}

return 0;

}

c语言浮点数乘法算法,单精度浮点数乘法的实现相关推荐

  1. C语言布斯乘法算法,布斯Booth算法带符号位的乘法verilog语言实现booth算法

    Booth算法的推倒表示看不懂,举例说明:算法的计算过程. 求M*Q的值 M=5,Q=6 按二进制分解M和Q :M3M2M1M0×Q3Q2Q1Q0: 0110×0101 (有符号数用补码表示,最高位表 ...

  2. 【软考学习3】数据表示——浮点数计算 + 单精度浮点数IEEE754计算

    浮点数计算在软考中的考查形式一般为选择题,要求选择正确的或者错误的是什么,所以需要学习浮点数的基本运算流程. 另外在本科<计算机组成原理>中还学过 IEEE754单精度 浮点数运算,所以一 ...

  3. C语言 int 转单精度浮点,单精度浮点数与十六进制转换 C语言程序 单片机也可用...

    单精度浮点数与十六进制转换 C语言程序 单片机也可用 #include float Hex_To_Decimal(unsigned char *Byte,int num)//十六进制到浮点数 { // ...

  4. c语言里单精度浮点数和双精度浮点数的区别

    单精度浮点数(float)和双精度浮点数(double)在C语言中是两种不同类型的数据.单精度浮点数占用4个字节的空间,精度范围在67位左右:双精度浮点数占用8个字节的空间,精度范围在1517位左右. ...

  5. 单精度浮点数转十进制C语言,C语言:IEEE754十进制数转二进制单精度浮点数

    1. 背景知识 IEEE754是由IEEE制定的有关浮点数的工业标准.针对于单精度浮点数,其公式如下,S为符号位,只占1位,为0表示正数,为1表示负数.P为指数(阶码),用移码表示,占8位.M为尾数, ...

  6. 双精度改单精度c语言程序,C语言菜鸟基础教程之单精度浮点数与双精度浮点数...

    上节课 简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的 ...

  7. c语言浮点数高精度求平方根,快速高精度的二进制浮点数开平方算法

    1引盲开平方运算在用徽机.单片机等构成的实时控制系统和测量仪器中有着广泛的应用.开平方运算的实现方法有多种:如牛顿迭代法.查表法.直线逼近法(线性化方法)和减奇数法等.对于查表法,当被开方数变化范围较 ...

  8. c语言浮点型菜鸟教程,C语言菜鸟基础教程之单精度浮点数与双精度浮点数

    上节课 简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的 ...

  9. c语言单精度浮点数规格化,对浮点数的一些理解

    浮点数的范围和有效位 对于浮点数,其能表示的数值范围和其有效位如下 类型 比特位 数值范围 有效位 float 32 -3.410^38-+3.410^38 6~7位 double 64 -1.710 ...

最新文章

  1. GNN 系列:Graph 基础知识介绍
  2. Bert时代的创新:Bert应用模式比较及其它
  3. Confluence 6 设置 Oracle 数据库准备
  4. IT人 不要一辈子靠技术生存(转
  5. Hadoop学习之hadoop安装、JDK安装、集群启动(完全分布式)
  6. 文件上传漏洞常用绕过方式
  7. 2021FME博客大赛 —— 利用FME实现三调地类图斑统计分析
  8. hive查看一张表的分区字段_在Hive中对表进行分区和存储有什么区别?
  9. Traffic Flow Prediction Using Graph Convolution Neural NetworksOC 翻译笔记
  10. 进程和线程的主仆问题
  11. Android Jetpack架构组件之Room
  12. 游戏建模入门教程:绝地求生—PUBG的游戏模型制作流程
  13. CSS设计指南---字体和文本的布局
  14. android苹果蓝牙版本,苹果蓝牙和安卓蓝牙能连吗
  15. 列表等份切割,Google Utils Lists partition
  16. JS 日期转换成时间戳
  17. 添加布林带择时策略有多便捷!股票量化分析工具QTYX-V2.4.7
  18. Objective-c中的占位符,打印BOOL类型数据
  19. C/C++黑魔法-字符串分割
  20. 全国计算机等级考试python教材.pdf_全国计算机等级考试二级教程Python语言程序设计(2018年版).PDF...

热门文章

  1. winDebug 调试
  2. Docker-windows使用教程
  3. 使用python绘制五角星
  4. 区块链技术研究热点有哪些
  5. 网页ssl证书风险怎么解决
  6. 常见分布律、分布函数、概率密度表,伯努利分布、二项分布、泊松分布、几何分布、超几何分布、均匀分布、高斯分布、指数分布
  7. 解决thinphp里返回json时斜杆和中文被转义问题
  8. python 实现多核 CPU 并行计算
  9. Oracle中日期函数的使用
  10. 完美黑苹果-蓝牙wifi-os10.15