title
收藏本站
联系站长
关于本站
首页 信息发布 产品宣传 论坛交流 学习文章 技术人生 项目源码 技术资料 人才收录
 今天是: 2010年7月10日 星期 六
欢迎光临!单片机群号:25930265(新) 71062262 21829895 64584393 26583231(只限加一群)  
热门文章推荐


当前位置:首页>>>单片机学习文章>> c51单片机浮点数及其汇编程序设计
c51单片机浮点数及其汇编程序设计
作者:tamson给他留言 [转载] 字体:
发表于:
2009-10-26 15:41:57
单片机应用系统的数据处理过程中,经常会遇到小数的运算问题,如求解BCD的增量算式、线性化处理等。因此,需要用二进制数来表示小数。表示小数的方法一般有两种,定点数和浮点数。定点数结构简单,与整数的运算过程相同,运算速度快。但随着所表示数的范围的扩大,其位数成倍增加,给运算和存储带来不便,而且也不能保证相对精度不变。浮点数的结构相对复杂,但它能够以固定的字节长度保持相对精度不变,用较少的字节表示很大的数的范围,便于存储和运算,在处理的数据范围较大和要求精度较高时,采用浮点数。 
浮点数的概念
    常用的科学计数法来表示一个十进制数如
    l234.75=1.23475E3=1.23475×103
    在数据很大或很小时,采用科学计数避免了在有效数字前加0来确定小数点的位置,突出了数据的有效数字的位数,简化了数据的表示。可以认为,科学计数法就是十进制数的浮点数表示方法。
    在二进制效中,也可以用类似的方法来表示一个数,如
    1234.75=10011010010.11(二进制)=0.1001101001011×211
一般表达式为
                           N=S×2p
    在这种表示方法中,数值由四个部分组成,即尾数S及符号,阶码P及符号。
在二进制中,通过定义相应字节或位来表示这四部分,就形成了二进制浮点数。二进制浮点数可以有多种不同的表示方法,下面是一种常见的三字节浮点数的格式:
    其中尾数占16位,阶码占6位,阶符占1位,数符占1位。阶码通常用补码来表示。
在这种表示方法中,小数点的实际位置要由阶码来确定,而阶码又是可变的,因此称为浮点数。
    1234.75用这种格式的浮点数表示就是:
0000 1011 1001 1010 0101 1000 
用十六进制表示为
1234.75=0B9A58H
-1234.75=4B9A58H
        0.171875=043B00H
-0.171875=443B00H
三字节浮点数所能表示的最大值为
                            1×263=9.22×1018
能表示的最小数的绝对值为
                            0.5×2-63=5.42×10-20
其所表示的数的绝对值范围=(5.42×10-20~9.22×1018),由此可以看到,比三字节定点数表示的数的范围大得多。
按同样方法可以定义一个四字节的浮点数,以满足更高精度的需要。
规格化浮点数
同一个数用浮点数表示可以是不同的,如
                       1234.75=0B9A58H=0C4D2CH=0D2696H
虽然这几种表示其数值是相同的,但其尾数的有效数字的位数不同,分别为16位、15位和14位。在运算过程中,为了最大限度地保持运算精度,应尽量增加尾数的有效位数。这就需要对浮点数进行规格化处理。
    在只考虑用二进制原码表示尾数时,尾数的最高位为l,则该浮点数为规格化浮点数。在规格化浮点数中,用尾数为0和最小阶码表示0,三字节规格化浮点数的0表示为410000H。
浮点数在运算之前和运算之后都要进行规格化,规格化过程包括以下步骤:
    (1)首先判断尾是否为0,如果为0,规格化结果为410000H;
    (2)如果尾数不为0,判断层数的最高位是否为1,如果不为1,尾数左移,阶码减1;
(3)再判断层数的最高位是否为1,如果不为1,继续进行规格化操作,如果为1,则规格化结束。
浮点数运算
    浮点数运算包括加、减、乘、除四则运算,比较运算,开方运算,多项式运算和函数运算。其它运算都可用这些基本运算的组合来完成。本节主要介绍浮点数四则运算及其子程序。
1.浮点数的加、减运算
浮点数的运算就是求结果的尾数、数符、阶码包括阶符的过程。在加、减运算中,参加运算的浮点数的阶码可能是不同的,其尾数所代表的值也是不同的。在这种情况下,尾数不能直接相加或相减,必须首先使两个数的阶相同,这一过程称为对阶。一般是让小阶向大阶对齐,尾数相应右移。对阶相当于算术中的小数点对齐或代数中的通分。尾数相加或相减得到了结果的尾数。数符由尾数的运算结果的符号确定。阶码就是两个数中较大的阶码。
例1  计算132.25+69.75
解: 132.25+69.75=088444H+078B80H=088444H+0845C0H=08CA00H=202
由于两个浮点数的阶码分别为8和7,先将加数的阶码变为8,其尾数右移1位。两个数的阶码相同后,尾数直接相加即为和的尾数,和的尾数的最高位为1,为规格化浮点数。
例2  计算12.39-93.1
解: 12.39-93.1=04C651H-07BA33H=87A169H=-80.71
本例中被减数小于减数,差为负数,结果的数符为1。差的阶码为两个数中较大的阶码。
2.浮点数乘法运算
如果设参加运算的两个操作数分别表示为
                         Na=(-1)SSa×Sa×2Pa
                         Nb=(-1)SSb ×Sb×2Pb
它们的积为
                         N=Na×Nb=(-1)SSa+SSb×(Sa×Sb)×2Pa+Pb
式中SSa和SSb为两个数的数符。
    乘法运算可总结为:
    (1)积的数符为乘数的符号位和被乘数的符号位按模2求和,即异或;
    (2)积的阶为乘数和被乘数的阶的和;
    (3)积的尾数为被乘数和乘数的尾数的积。
    参加运算的浮点数一般都是规格化的浮点数,尾数的积小于1,不需进行右规格化处理。但有可能小于0.5,所以需进行左规格化处理,使积为规格化浮点数。如果乘数或被乘数的尾为0、则积为410000H。由于在尾数相乘时,积的低16位不能反映在结果中,因此,积可能会产生一定的误差。
例3  算22.4l×4.23。
解: 22.41×4.23=05B349H×03875EH=07BD9AH=94.8
    积的阶为乘数和被乘数的和,即8。尾数相乘时,积小于0.5,进行左规格化处理,阶码变为7。
例4  计算2586.5×(-6.91)。
解: 2586.5×(-6.91)=0CA1BOH×83DD13H=8F8BA0H=-17872
    被乘数为正数,数符为0,乘数为负数,数符为1,积的数符为0⊕1=1,积为负数。
3.浮点数的除法运算
除法运算可以表示为
N=Na/Nb=[(-1)SSa×Sa×2Pa]/[(-1)SSb×Sb×2Pb ]
                     =(-1)SSa-SSb×(Sa/Sb) ×2Pa-Pb
浮点数的除法运算可以总结为:
(1) 商的数符为被除数与除数的符号位的差;
(2) 商的阶码为被除数和除数的阶码的差;
(3)  商的尾数为被除数和除数的尾数的商。
规格化的浮点数进行除法运算时,尾数相除,商不会小于0.5,不需进行左规格化处理。但有可能大于1,有时需进行右规格化处理。
例5  计算390.67÷14.3l。
解:  390.67÷14.31=09C357H÷04E511H=05DA4EH=27.3
商的阶码为被除数与除数的阶码的差。尾数相除时,结果的最高位为1,商为规格化浮点数。
例6  计算 -6.02÷16.157。
    解:  -6.02÷16.157=83C0AAH÷058143H=FFBEC8H= -0.373
异号相除时,商为负数。由于被除数的尾数大于除数的尾数,所以被除数先进行右规格化,阶码变为4,商的阶码为 -1,用补码来表示。
浮点数运算子程序
    通过前面的分析可以看到,浮点运算比较复杂,有其特有的方法和规律。这里介绍几种常用的三字节浮点数运算子程序,通过分析、设计这些程序,可以进一步了解浮点数的运算过程和特点,熟悉复杂程序的设计方法。
1.浮点数通用规格化子程序
    在浮点数运算过程中,有时需要左规格化,有时需要右规格化。通过规格化子程序既可实现左规格化,又可实现右规格化,其具体功能如下:
    当Cy=0时,进行右规格化:F0=0时.对R6(阶)R2R3(尾数)右规格化1位;F0=1时,对R7(阶)R4R5(尾数)右规格化1位。
当Cy=1时,对R6(阶)R3R3(尾数)执行左规格化。
程序开始时,判断是执行左规格化还是右规格化。如果是右规格化,还要判断是对R6(阶)R2R3(尾数)还是对R7(阶)R4R5(尾数)进行规格化。如果是左规格化,直至把操作数变为规格化浮点数。其程序框图如图4-13所示。程序为:
FSDT: JC  LNORMS
  MOV  C, 39H       ;进行右规格化
  JB  F0, NR7  
  MOV  A, R2       ;R2R3右移一位
  RRC  A        ;(Cy)移入尾数最高位
  MOV  R2, A
  MOV  A, R3
  RRC  A
  MOV  R3, A
  INC  R6        ;阶码加1
RET 
 NR7:  MOV  A, R4
   RRC  A
   MOV  R4, A
   MOV  A, R5
   RRC  A
   MOV  R5, A
   INC  R7
   RET
LNORMS:  MOV  A, R7
   JNZ  LSHIFT
   CJNE  R3, #00H, LSBIT8  ;尾数为0,阶码41H
   MOV  R6, #41H
LSEND :  RET
LSHIFT:  JB  ACC.7, LSEND
LSBIT8:  MOV  C, F0
   MOV  A, R3
   RLC  A
   MOV  R3, A
   MOV  A, R2
   RLC  A
   MOV  R2, A
   CLR  F0
   DEC  R6
   SJMP  LNORMS
2.浮点数加减运算子程序
    参加运算的浮点数可能是正数,也可能是负数。对于加法运算.当加数和被加数的数符相同时,尾数相加,不同时尾数相减;对于减法运算,当减数和被减数的数符相同时,尾数相减、不同时尾数相加。当两个浮点数的阶码不同时,要进行对阶,使小阶与大阶相等,因此,结果的阶码与其较大的阶码相同。
    在执行加法运算时,尾数有可能大于1,因此要进行右规格化处理;执行减法运算时,尾数有可能小于0.5,因此,要进行左规格化处理。
    下面是三字节浮点数加、减法处理于程序,具体功能为:
        R6(阶)R2R3(尾)±R7(阶)R4R5(尾)→R4(阶)R2R3(尾);
    当位3AH=0时,执行加法;
    当位3AH=1时,执行减法。
    程序框图如图4—14所示。程序如下:
FABP:   MOV  A, R6
  MOV  C, ACC.7
  MOV  38H, C      ;存被加数数符
  XRL  A, R7
JNB  ACC.7, FAB1 ;数符相同则转
  CPL  3AH   ;数符不等,求反运算标志
图4-14
FAB1: MOV  A, R6
MOV  C, ACC.6      ;扩展阶码符号位
  MOV  ACC.7, C
  MOV  R6, A
  MOV  A, R7
  CLR  C
  MOV  A, R6
  SUBB  A, R7
  JZ  FAB2      ;阶码相同则转
  CLR  F0
  JB  ACC.7, FAB6
  CJNE  R4, #00H, FAB7
  CJNE  R5, #00H, FAB7
FAB2: JB  3AH, FAB9      ;转向尾数减法
  MOV  A, R3  ;执行尾数加法
  ADD  A, R5
  MOV  R3, A
  ADD  A, R2
  ADDC  A, R4
  MOV  R2, A
  JNC  FAB4
  SETB  39H
  CLR  C
FAB3: CLR  F0
  LCALL FSDT
FAB4: CJNE  R2, #00H, FAB5
  CJNE  R3, #00H, FAB5
  MOV  R4, #41    ;结果为0,规格化
  RET
FAB5: MOV  A, R6
  MOV  C, 38H
  MOV  ACC.7, C
  XCH  A, R4
  MOV  R6, A
  RET
FAB6: CJNE  R2, #00H, FAB8
  CJNE  R3, #00H, FAB8
  MOV  A, R7
  MOV  R6, A
  SJMP  FAB2
FAB7: CPL  F0
FAB8: CLR  C
  LCALL FSDT
  SJMP  FAB1
FAB9: MOV  A, R3     ;尾数相减
  CLR  C
  SUBB  A, R5
  MOV  R3, A
  MOV  A, R2
  SUBB  A, R4
  MOV  R2, A
  JNC  FAB10
  CLR  A
  CLR  C
  SUBB  A, R3
  MOV  R3, A
  CLR  A
  SUBB  A, R2
  MOV  R2, A
  CPL  38H
FAB10: SETB C
  SJMP FAB3
3. 浮点数乘法运算子程序
浮点数相乘时,阶码直接相加即获得积的阶码,尾数相乘时,结果可能小于0.5,需进行左规格化处理。下面是三字节浮点数乘法运算子程序,具体功能为:
    (Ro)指向的三字节浮点数×(R1)指向的三字节浮点数→R4(阶)R2R3(尾数)。
图4-15三字节浮点数乘法的程序框图。程序为:
  FMUL: LCALL FMLD   ;传送浮点数
    MOV  A, R6  ;求积的数符
    XRL  A, R7
    MOV  C, ACC.7                    
    MOV  38H, C
    LCALL DMUL   ;调用双字节无符号数乘法子程序
    MOV  A, R7
    MOV  C, ACC.7 
    MOV  F0, C
    MOV  A, @R0
    ADD  A, @R1
    MOV  R6, A
    SETB  C
    LCALL FSDT   ;进行规格化操作
图4-15 三字节浮点数乘法子程序
    MOV  A, R6
    MOV  C, 38H
    MOV  ACC.7, C  ;置积的数符
    MOV  R4, A
    RET
    注:(1)FMLD为浮点数取数子程序,功能为:将(R0)指向的三字节浮点数送入R6(阶)R2R3(尾数)中,将(R1)指向的三字节浮点数送入R7(阶)R4R5(尾数)中。
    (2)DMUL为双字节无符号数乘法子程序。
4.浮点数除法运算子程序
在进行除法运算时,被除数的尾数可能比除数的尾数大很多,使结果大于1。为避免这种情况,如果被除数尾数大于除数的尾数,先将被除数的尾数右移,使其小于除数的尾数。阶码也相应增加,保持其数值不变。下面是三字节浮点数除法运算程序,其功能为:(R0)指向的三字节浮点数除以(R1)指向的三字节浮点数→R4(阶)R2R3(尾数)中。
程序框图如图4-16所示。程序为:
 FDIV: LCALL FMLD
   MOV  A, R6
   XRL  A, R7     ;求商的数符
   MOV  C, ACC.7
   MOV  38H, C
   CLR  A
   MOV  R6, A
   MOV  R7, A
   CJNE  R4, #00H, FDIV1
CJNE  R5, #00H, FDIV1
   SETB  C
   RET             ;除数为0返回
FDIV1: MOV  A, R3     ;比较被除数与
SUBB  A, R5       ;除数的尾数
   MOV  A, R2
   SUBB  A, R4
   JC  FDIV2
   CLR  F0
   CLR  39H
   LCALL FDST
   RRC  A
   MOV  R7, A
   CLR  C
   SJMP  FDIV1
 FDIV2: CLR  A
   XCH  A, R6
   PUSH  ACC
   LCALL DDIV      ;调用双字节除法程序
   POP  ACC
   ADD  A, @R0
   CLR  C
   SUBB  A, @R1
   MOV  C, 38H 
MOV  ACC.7, C
MOV  R4, A
CLR  C
RET
(本文引自www.mcujl.com/article.asp?conID=472)


---------------------------------------------------------------------------------------------------
[打印文章] [关闭本页] [返回顶部]
本网站部分资料转自网上,如有侵权请来信告明,我们会尽快删除  | 网站地图
Copyright @ 2007-2010 深圳单片机交流网.版权所有
网站创办者:詹长亮,周发辉,李林盛
网站支持:zcl843@163.com QQ:380476830 13723787271詹长亮