




已阅读5页,还剩4页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
浮点数显示C51里用4字节存储一个浮点数,格式遵循IEEE-754标准(详见c51.pdf第179页说明)。一个浮点数用两个部分表示,尾数和2的幂,尾数代表浮点上的实际二进制数,2的幂代表指数,指数的保存形式是一个0到255的8位值,指数的实际值是保存值(0到255)减去127,一个范围在-127到+128之间的值,尾数是一个24位值(代表大约7个十进制数),最高位MSB通常是1,因此不保存。一个符号位表示浮点数是正或负。浮点数保存的字节格式如下: 地址+0+1+2+3 内容SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM 这里 S代表符号位,1是负,0是正 E偏移127的幂,二进制阶码=(EEEEEEEE)-127。 M24位的尾数保存在23位中,只存储23位,最高位固定为1。此方法用最较少的位数实现了较高的有效位数,提高了精度。 零是一个特定值,幂是0尾数也是0。 浮点数-12.5作为一个十六进制数0xC1480000保存在存储区中,这个值如下: 地址+0+1+2+3 内容0xC10x480x000x00 浮点数和十六进制等效保存值之间的转换相当简单。下面的例子说明上面的值-12.5如何转换。 浮点保存值不是一个直接的格式,要转换为一个浮点数,位必须按上面的浮点数保存格式表 所列的那样分开,例如: 地址+0+1+2+3 格式SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM 二进制11000001010010000000000000000000 十六进制C1480000 从这个例子可以得到下面的信息: 符号位是1表示一个负数 幂是二进制10000010或十进制130,130减去127是3,就是实际的幂。 尾数是后面的二进制数10010000000000000000000 在尾数的左边有一个省略的小数点和1,这个1在浮点数的保存中经常省略,加上一个1和小数 点到尾数的开头,得到尾数值如下: 1.10010000000000000000000 接着,根据指数调整尾数.一个负的指数向左移动小数点.一个正的指数向右移动小数点.因为 指数是3,尾数调整如下: 1100.10000000000000000000 结果是一个二进制浮点数,小数点左边的二进制数代表所处位置的2的幂,例如:1100表示 (1*23)+(1*22)+(0*21)+(0*20)=12。 小数点的右边也代表所处位置的2的幂,只是幂是负的。例如:.100.表示(1*2(-1)+ (0*2(-2)+(0*2(-2).=0.5。 这些值的和是12.5。因为设置的符号位表示这数是负的,因此十六进制值0xC1480000表示- 12.5。 浮点数错误信息 8051没有包含捕获浮点数错误的中断向量,因此,你的软件必须正确响应这些错误情 况。 除了正常的浮点数值,还包含二进制错误值。这些值被定义为IEEE标准的一部分并用在 正常浮点数操作过程中发生错误的时候。你的代码应该在每一次浮点操作完成后检查可能出 现的错误。 名称值含义 NaN0xFFFFFFF不是一个数 +INF0x7F80000正无穷(正溢出) -INF0xFF80000负无穷(负溢出) 你可以使用如下的联合体(union)存储浮点数。 unionf floatf;/浮点值 unsignedlongul;/无符号长整数 ; 这个union包含一个float和一个unsignedlong以便执行浮点数学运算并响应IEEE错误状态。 以上是KEIL在线帮助的中译文,下面我们讨论如何显示浮点数。 尾数为24bit,最高可表达的整数值为224-1=16777215,也就是说,小于等于16777215的整数可以被精确显示。这决定了十进制浮点数的有效位数为7位,10716777215108, 10的7次方以内的数小于16777215,可以精确表示。使用科学记数法时,整数部分占1位,所以小数部分最大占7-1=6位,即最大有6位十进制精度。 长整形数和浮点数都占4字节,但表示范围差别很大。浮点数的范围为+-1.175494E-38到+-3.402823E+38,无符号长整形数范围为0到4294967295。显示浮点数要用到长整形数保存数据,可他们范围差这么多,怎么办呢? 仔细观察十进制浮点数的显示,有一个尾数和一个阶码,由上面论证可知32位IEEE-754浮点数最大有效数字为7位十进制数,超出此范围的数字有截断误差,不必理会,因此,浮点数尾数能够放在长整形数里保存。阶码为-38到38,一个char型变量就可以保存。 综上所述,以107的最大跨度为窗口(小于107也可以,如:10,100.10000等,但决 不能大于它,那样会超出精度范围),定位浮点数的量级,然后取出7位尾数的整数值存于长 整形数里,再调整阶码,就可以精确显示此浮点数。 量级尺度如下: (-38)-(-35)-(-28)-(-21)-(-14)-(-7)-(0)-(7)-(14)-(21)-(28)-(35)-(38) 请严格按照KEIL手册给出的浮点数范围显示,因为数值空间没有完全使用,有些值用于错误指示和表示正负无穷。小于1.175494E-38的数仍可以显示一些,但最好不用,以免出错。我采用直接判断的方法,剔除此种情况。 在计算机里结合律不成立,(a*b)*c!=a*(b*c),原则是先让计算结果值动态范围小的两个数运算,请注意程序里的写法。 注:(1E38/b)*1E6不要写成1E44/b,因为无法在32位浮点数里保存1E44,切记! 计算机使用二进制数计算,能有效利用电子器件高速开关的特性,而人习惯于十进制数表示,二进制和十进制没有方便的转换方法,只能通过大量计算实现,浮点数的十进制科学记数法显示尤其需要大量的运算,可见,显示一个浮点数要经过若干次浮点运算,没有必要就不要显示,否则,花在显示上的时间比计算的耗时都要多得多。 源程序: /= = / /= = voidDispF(floatf)reentrant/用科学记数法显示浮点数,在float全范围内精确显 示,超出范围给出提示。 /+-1.175494E-38到+-3.402823E+38 floattf,b; unsignedlongw,tw; chari,j; if(f0) PrintChar(-); f=-1.0*f; if(f1E35)/f1035 tf=f/1E35; b=1000.0; for(i=0,j=38;i4;i+,j-) if(tf/b1E28)/1028f=1035 tf=f/1E28; b=1E7; for(i=0,j=35;i8;i+,j-) if(tf/b1E21)/1021f=1028 tf=f/1E21; b=1E7; for(i=0,j=28;i8;i+,j-) if(tf/b1E14)/1014f=1021 tf=f/1E14; b=1E7; for(i=0,j=21;i8;i+,j-) if(tf/b1E7)/107f=1014 tf=f/1E7; b=1E7; for(i=0,j=14;i8;i+,j-) if(tf/b1)/1f=107 tf=f; b=1E7; for(i=0,j=7;i8;i+,j-) if(tf/b1E-7)/10-7f=1 tf=f*1E7; b=1E7; for(i=0,j=0;i8;i+,j-) if(tf/b1E-14)/10-14f=10-7 tf=f*1E14; b=1E7; for(i=0,j=-7;i8;i+,j-) if(tf/b1E-21)/10-21f=10-14 tf=f*1E21; b=1E7; for(i=0,j=-14;i8;i+,j-) if(tf/b1E-28)/10-28f=10-21 tf=f*1E28; b=1E7; for(i=0,j=-21;i8;i+,j-) if(tf/b1E-35)/10-35f=10-28 tf=f*1E35; b=1E7; for(i=0,j=-28;i8;i+,j-) if(tf/b1)b=b/10.0; elsebreak; w=f*(1E35/b)*1E6;/(1E35/b)*1E6 PrintW(w,j); else/f=10-35 tf=f*1E38; b=1000.0; for(i=0,j=-35;i4;i+,j-) if(tf/b1)b=b/10.0; elsebreak; w=f*(1E38/b)*1E6;/(1E38/b)*1E6 PrintW(w,j); voidPrintW(unsignedlongw,charj)reentrant/科学记数法,显示十进制尾数和阶 码。 chari; unsignedlongtw,b; /if(j38)yyprintf(*.*);return;此算法不会出现j38的情况。 tw=w/1000000; PrintChar(tw+0);PrintChar(.); w=w-tw*1000000; b=100000; for(i=0;i0?varForLog.dblVal:-varForLog.dblVal) + 1;int nRound = DELTA_RATE - nIntCount;return nRound;double doublAdd2(double dbl1, double dbl2)COleVariant var(dbl1+dbl2);int r1 = getRound(dbl1);int r2 = getRound(dbl2);:VarRound(&var,max(r1,r2),&var);return var.dblVal;做过一些实验,好象是正确的。同理可以实现doubleSub2的函数。注意:这里并不用下面五所提的取精度的方式,因为取精度的运算更低效。五:对于乘除法呢?问题有些复杂,先找出一个需要处理的例子。如:2.01*2.01=4.0401。试了一下,不成立。用方法一的Decimal方式测试,可以通过。那么方法二呢?再做假设吧,假设dbl1有两位小数,dbl2也有两位小数,按理论,可得出相乘后,最大可能是2+2位小数。那么,我们按照 4位小数进行Round处理,可能会得出正确的结果。实际上,要取一个双精度的10进制表达的小数位,我没有找到什么好办法,我能想到的:也就是将数字转为字串,然后查找.后的位数。这样,显然是非常低效的,这里,我就不再写出代码了。六:比较方法一和方法二。方法二并不高效,并且还有一些不定因素,所以,最好采用方法一来统一处理浮点数的运算。至于效率,实际上最佳方法是从程序的设计着手,将double从程序中去除掉。比如在VC中,可以用Variant:Decimal来彻底
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 牧场节水措施方案范本
- 驻马店从业资格考试题及答案解析
- 作业人员工地安全题库及答案解析
- 小钟琴师资培训
- 语文教学经验分享课件
- 高二语文长相思教学课件
- 减胎术护理查房要点
- 运输企业汛期安全培训课件
- 钉钉教学课件使用方法
- 压力性损伤护理教学查房
- 植物生理学第十三章植物的逆境生理课件
- 2022年资阳市雁江区社区工作者招聘考试笔试试题及答案解析
- 2.2 第2课时 基本不等式的综合应用(课件)高一数学(人教A版2019必修第一册)
- 帮助卧床老年人使用便器排便课件
- 勿忘国耻教学课件
- 【高考英语精品专题】必修1 Unit 1 Life Choices-高考英语-一轮总复习备考方略课件PPT(新教材北师大版)
- 中国传媒大学-新媒体概论(刘行芳)-课件
- 医学放射卫生相关法律法规ppt培训课件
- 《中国音乐发展简史》PPT课件
- SLZ 549-2012 用水审计技术导则(试行)
- 颈内动脉动脉瘤临床路径(2010年版)
评论
0/150
提交评论