51单片机浮点运算子程序库
2012-06-02
标签:

为便于读者使用本程序库,先将有关约定说明如下:

1.双字节定点操作数:用[R0]或[R1]来表示存放在由R0或R1指示的连续单元中的数据,地址小的单元存放高字节。如果[R0]=1234H,若(R0)=30H,则(30H)=12H,(31H)=34H。

2.二进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节纯小数(原码)来表示。当尾数的最高位为1时,便称为规格化浮点数,简称操作数。在程序说明中,也用[R0]或[R1]来表示R0或R1指示的浮点操作数,例如:当[R0]=-6.000时,则二进制浮点数表示为83C000H。若(R0)=30H,则(30H)=83H,(31H)=0C0H,(32H)=00H。

3.十进制浮点操作数:用三个字节表示,第一个字节的最高位为数符,其余七位为阶码(二进制补码形式),第二字节为尾数的高字节,第三字节为尾数的低字节,尾数用双字节BCD码纯小数(原码)来表示。当十进制数的绝对值大于1时,阶码就等于整数部分的位数,如 876.5 的阶码是03H,-876.5 的阶码是 83H;当十进制数的绝对值小于1时,阶码就等于 80H 减去小数点后面零的个数,例如 0.00382 的阶码是 7EH,-0.00382的阶码是 0FEH。在程序说明中,用[R0]或[R1]来表示R0或R1指示的十进制浮点操作数。例如有一个十进制浮点操作数存放在30H、31H、32H中,数值是 -0.07315,即-0.7315乘以10的-1次方,则(30H)=0FFH,31H=73H,(32H)=15H。若用[R0]来指向它,则应使(R0)=30H。

4.运算精度:单次定点运算精度为结果最低位的当量值;单次二进制浮点算术运算的精度优于十万分之三;单次二进制浮点超越函数运算的精度优于万分之一;BCD码浮点数本身的精度比较低(万分之一到千分之一),不宜作为运算的操作数,仅用于输入或输出时的数制转换。不管那种数据格式,随着连续运算的次数增加,精度都会下降。

5.工作区:数据工作区固定在A、B、R2~R7,数符或标志工作区固定在PSW和23H单元(位1CH~1FH)。在浮点系统中,R2、R3、R4和位1FH为第一工作区,R5、R6、R7和位1EH为第二工作区。用户只要不在工作区中存放无关的或非消耗性的信息,程序就具有较好的透明性。

6.子程序调用范例:由于本程序库特别注意了各子程序接口的相容性,很容易采用积木方式(或流水线方式)完成一个公式的计算。以浮点运算为例:

计算 y = Ln √ | Sin (ab/c+d) |

已知:a=-123.4;b=0.7577;c=56.34;d=1.276; 它们分别存放在30H、33H、36H、39H开始的连续三个单元中。用BCD码浮点数表示时,分别为a=831234H;b=007577H;c=025634H;d=011276H。

求解过程:通过调用BTOF子程序,将各变量转换成二进制浮点操作数,再进行各

种运算,最后调用FTOB子程序,还原成十进制形式,供输出使用。程序如下:

TEST:   MOV R0,#39H    ;指向BCD码浮点操作数d
        LCALL BTOF     ;将其转换成二进制浮点操作数
        MOV R0,#36H    ;指向BCD码浮点操作数c
        LCALL BTOF     ;将其转换成二进制浮点操作数
        MOV R0,#33H    ;指向BCD码浮点操作数b
        LCALL BTOF     ;将其转换成二进制浮点操作数
        MOV R0,#30H    ;指向BCD码浮点操作数a
        LCALL BTOF     ;将其转换成二进制浮点操作数
        MOV R1,#33H    ;指向二进制浮点操作数b
        LCALL FMUL     ;进行浮点乘法运算
        MOV R1,#36H    ;指向二进制浮点操作数c
        LCALL FDIV     ;进行浮点除法运算
        MOV R1,#39H    ;指向二进制浮点操作数d
        LCALL FADD     ;进行浮点加法运算
        LCALL FSIN     ;进行浮点正弦运算
        LCALL FABS     ;进行浮点绝对值运算
        LCALL FSQR     ;进行浮点开平方运算
        LCALL FLN      ;进行浮点对数运算
        LCALL FTOB     ;将结果转换成BCD码浮点数
STOP:   LJMP STOP
        END

运行结果,[R0]=804915H,即y=-0.4915,比较精确的结果应该是-0.491437。

(1)FSDT 功能:浮点数格式化

入口条件:待格式化浮点操作数在[R0]中。

出口信息:已格式化浮点操作数仍在[R0]中。

影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节

FSDT:   LCALL MVR0     ;将待格式化操作数传送到第一工作区中
        LCALL RLN      ;通过左规完成格式化
        LJMP MOV0      ;将已格式化浮点操作数传回到[R0]中

(2)FADD 功能:浮点数加法

入口条件:被加数在[R0]中,加数在[R1]中。

出口信息:OV=0时,和仍在[R0]中,OV=1时,溢出。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 6字节

FADD:   CLR F0         ;设立加法标志
        SJMP AS        ;计算代数和

(3)FSUB 功能:浮点数减法

入口条件:被减数在[R0]中,减数在[R1]中。

出口信息:OV=0时,差仍在[R0]中,OV=1时,溢出。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

FSUB:   SETB F0        ;设立减法标志
AS:     LCALL MVR1     ;计算代数和。先将[R1]传送到第二工作区
        MOV C,F0       ;用加减标志来校正第二操作数的有效符号
        RRC A
        XRL A,@R1
        MOV C,ACC.7
ASN:    MOV 1EH,C      ;将第二操作数的有效符号存入位1EH中
        XRL A,@R0      ;与第一操作数的符号比较
        RLC A
        MOV F0,C       ;保存比较结果
        LCALL MVR0     ;将[R0]传送到第一工作区中
        LCALL AS1      ;在工作寄存器中完成代数运算
MOV0:   INC R0         ;将结果传回到[R0]中的子程序入口
        INC R0
        MOV A,R4       ;传回尾数的低字节
        MOV @R0,A
        DEC R0
        MOV A,R3       ;传回尾数的高字节
        MOV @R0,A
        DEC R0
        MOV A,R2       ;取结果的阶码
        MOV C,1FH      ;取结果的数符
        MOV ACC.7,C    ;拼入阶码中
        MOV @R0,A
        CLR ACC.7      ;不考虑数符
        CLR OV         ;清除溢出标志
        CJNE A,#3FH,MV01       ;阶码是否上溢?
        SETB OV        ;设立溢出标志
MV01:   MOV A,@R0      ;取出带数符的阶码
        RET
MVR0:   MOV A,@R0      ;将[R0]传送到第一工作区中的子程序
        MOV C,ACC.7    ;将数符保存在位1FH中
        MOV 1FH,C
        MOV C,ACC.6    ;将阶码扩充为8bit补码
        MOV ACC.7,C
        MOV R2,A       ;存放在R2中
        INC R0
        MOV A,@R0      ;将尾数高字节存放在R3中
        MOV R3,A
        INC R0
        MOV A,@R0      ;将尾数低字节存放在R4中
        MOV R4,A
        DEC R0         ;恢复数据指针
        DEC R0
        RET
MVR1:   MOV A,@R1      ;将[R1]传送到第二工作区中的子程序
        MOV C,ACC.7    ;将数符保存在位1EH中
        MOV 1EH,C
        MOV C,ACC.6    ;将阶码扩充为8bit补码
        MOV ACC.7,C
        MOV R5,A       ;存放在R5中
        INC R1
        MOV A,@R1      ;将尾数高字节存放在R6中
        MOV R6,A
        INC R1
        MOV A,@R1      ;将尾数低字节存放在R7中
        MOV R7,A
        DEC R1         ;恢复数据指针
        DEC R1
        RET
AS1:    MOV A,R6       ;读取第二操作数尾数高字节
        ORL A,R7
        JZ AS2         ;第二操作数为零,不必运算
        MOV A,R3       ;读取第一操作数尾数高字节
        ORL A,R4
        JNZ EQ1
        MOV A,R6       ;第一操作数为零,结果以第二操作数为准
        MOV R3,A
        MOV A,R7
        MOV R4,A
        MOV A,R5
        MOV R2,A
        MOV C,1EH
        MOV 1FH,C
AS2:    RET
EQ1:    MOV A,R2       ;对阶,比较两个操作数的阶码
        XRL A,R5
        JZ AS4         ;阶码相同,对阶结束
        JB ACC.7,EQ3   ;阶符互异
        MOV A,R2       ;阶符相同,比较大小
        CLR C
        SUBB A,R5
        JC EQ4
EQ2:    CLR C          ;第二操作数右规一次
        MOV A,R6       ;尾数缩小一半
        RRC A
        MOV R6,A
        MOV A,R7
        RRC A
        MOV R7,A
        INC R5         ;阶码加一
        ORL A,R6       ;尾数为零否?
        JNZ EQ1        ;尾数不为零,继续对阶
        MOV A,R2       ;尾数为零,提前结束对阶
        MOV R5,A
        SJMP AS4
EQ3:    MOV A,R2       ;判断第一操作数阶符
        JNB ACC.7,EQ2  ;如为正,右规第二操作数
EQ4:    CLR C
        LCALL RR1      ;第一操作数右规一次
        ORL A,R3       ;尾数为零否?
        JNZ EQ1        ;不为零,继续对阶
        MOV A,R5       ;尾数为零,提前结束对阶
        MOV R2,A
AS4:    JB F0,AS5      ;尾数加减判断
        MOV A,R4       ;尾数相加
        ADD A,R7
        MOV R4,A
        MOV A,R3
        ADDC A,R6
        MOV R3,A
        JNC AS2
        LJMP RR1       ;有进位,右规一次
AS5:    CLR C          ;比较绝对值大小
        MOV A,R4
        SUBB A,R7
        MOV B,A
        MOV A,R3
        SUBB A,R6
        JC AS6
        MOV R4,B       ;第一尾数减第二尾数
        MOV R3,A
        LJMP RLN       ;结果规格化
AS6:    CPL 1FH        ;结果的符号与第一操作数相反
        CLR C          ;结果的绝对值为第二尾数减第一尾数
        MOV A,R7
        SUBB A,R4
        MOV R4,A
        MOV A,R6
        SUBB A,R3
        MOV R3,A
RLN:    MOV A,R3       ;浮点数规格化
        ORL A,R4       ;尾数为零否?
        JNZ RLN1
        MOV R2,#0C1H   ;阶码取最小值
        RET
RLN1:   MOV A,R3
        JB ACC.7,RLN2  ;尾数最高位为一否?
        CLR C          ;不为一,左规一次
        LCALL RL1
        SJMP RLN       ;继续判断
RLN2:   CLR OV         ;规格化结束
        RET
RL1:    MOV A,R4       ;第一操作数左规一次
        RLC A          ;尾数扩大一倍
        MOV R4,A
        MOV A,R3
        RLC A
        MOV R3,A
        DEC R2         ;阶码减一
        CJNE R2,#0C0H,RL1E     ;阶码下溢否?
        CLR A
        MOV R3,A       ;阶码下溢,操作数以零计
        MOV R4,A
        MOV R2,#0C1H
RL1E:   CLR OV
        RET
RR1:    MOV A,R3       ;第一操作数右规一次
        RRC A          ;尾数缩小一半
        MOV R3,A
        MOV A,R4
        RRC A
        MOV R4,A
        INC R2         ;阶码加一
        CLR OV         ;清溢出标志
        CJNE R2,#40H,RR1E      ;阶码上溢否?
        MOV R2,#3FH    ;阶码溢出
        SETB OV
RR1E:   RET

(4)FMUL 功能:浮点数乘法

入口条件:   被乘数在[R0]中,乘数在[R1]中。

出口信息:   OV=0时,积仍在[R0]中,OV=1时,溢出。

影响资源:   PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

FMUL:   LCALL MVR0     ;将[R0]传送到第一工作区中
        MOV A,@R0
        XRL A,@R1      ;比较两个操作数的符号
        RLC A
        MOV 1FH,C      ;保存积的符号
        LCALL MUL0     ;计算积的绝对值
        LJMP MOV0      ;将结果传回到[R0]中
MUL0:   LCALL MVR1     ;将[R1]传送到第二工作区中
MUL1:   MOV A,R3       ;第一尾数为零否?
        ORL A,R4
        JZ MUL6
        MOV A,R6       ;第二尾数为零否?
        ORL A,R7
        JZ MUL5
        MOV A,R7       ;计算R3R4×R6R7-→R3R4
        MOV B,R4
        MUL AB
        MOV A,B
        XCH A,R7
        MOV B,R3
        MUL AB
        ADD A,R7
        MOV R7,A
        CLR A
        ADDC A,B
        XCH A,R4
        MOV B,R6
        MUL AB
        ADD A,R7
        MOV R7,A
        MOV A,B
        ADDC A,R4
        MOV R4,A
        CLR A
        RLC A
        XCH A,R3
        MOV B,R6
        MUL AB
        ADD A,R4
        MOV R4,A
        MOV A,B
        ADDC A,R3
        MOV R3,A
        JB ACC.7,MUL2  ;积为规格化数否?
        MOV A,R7       ;左规一次
        RLC A
        MOV R7,A
        LCALL RL1
MUL2:   MOV A,R7
        JNB ACC.7,MUL3
        INC R4
        MOV A,R4
        JNZ MUL3
        INC R3
        MOV A,R3
        JNZ MUL3
        MOV R3,#80H
        INC R2
MUL3:   MOV A,R2       ;求积的阶码
        ADD A,R5
MD:     MOV R2,A       ;阶码溢出判断
        JB ACC.7,MUL4
        JNB ACC.6,MUL6
        MOV R2,#3FH    ;阶码上溢,设立标志
        SETB OV
        RET
MUL4:   JB ACC.6,MUL6
MUL5:   CLR A          ;结果清零(因子为零或阶码下溢)
        MOV R3,A
        MOV R4,A
        MOV R2,#41H
MUL6:   CLR OV
        RET

(5)FDIV 功能:浮点数除法

入口条件:被除数在[R0]中,除数在[R1]中。

出口信息:OV=0时,商仍在[R0]中,OV=1时,溢出。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节

FDIV:   INC R0
        MOV A,@R0
        INC R0
        ORL A,@R0
        DEC R0
        DEC R0
        JNZ DIV1
        MOV @R0,#41H   ;被除数为零,不必运算
        CLR OV
        RET
DIV1:   INC R1
        MOV A,@R1
        INC R1
        ORL A,@R1
        DEC R1
        DEC R1
        JNZ DIV2
        SETB OV        ;除数为零,溢出
        RET
DIV2:   LCALL MVR0     ;将[R0]传送到第一工作区中
        MOV A,@R0
        XRL A,@R1      ;比较两个操作数的符号
        RLC A
        MOV 1FH,C      ;保存结果的符号
        LCALL MVR1     ;将[R1]传送到第二工作区中
        LCALL DIV3     ;调用工作区浮点除法
        LJMP MOV0      ;回传结果
DIV3:   CLR C          ;比较尾数的大小
        MOV A,R4
        SUBB A,R7
        MOV A,R3
        SUBB A,R6
        JC DIV4
        LCALL RR1      ;被除数右规一次
        SJMP DIV3
DIV4:   CLR A          ;借用R0R1R2作工作寄存器
        XCH A,R0       ;清零并保护之
        PUSH ACC
        CLR A
        XCH A,R1
        PUSH ACC
        MOV A,R2
        PUSH ACC
        MOV B,#10H     ;除法运算,R3R4/R6R7-→R0R1
DIV5:   CLR C
        MOV A,R1
        RLC A
        MOV R1,A
        MOV A,R0
        RLC A
        MOV R0,A
        MOV A,R4
        RLC A
        MOV R4,A
        XCH A,R3
        RLC A
        XCH A,R3
        MOV F0,C
        CLR C
        SUBB A,R7
        MOV R2,A
        MOV A,R3
        SUBB A,R6
        ANL C,/F0
        JC DIV6
        MOV R3,A
        MOV A,R2
        MOV R4,A
        INC R1
DIV6:   DJNZ B,DIV5
        MOV A,R6       ;四舍五入
        CLR C
        RRC A
        SUBB A,R3
        CLR A
        ADDC A,R1      ;将结果存回R3R4
        MOV R4,A
        CLR A
        ADDC A,R0
        MOV R3,A
        POP ACC        ;恢复R0R1R2
        MOV R2,A
        POP ACC
        MOV R1,A
        POP ACC
        MOV R0,A
        MOV A,R2       ;计算商的阶码
        CLR C
        SUBB A,R5
        LCALL MD       ;阶码检验
        LJMP RLN       ;规格化

(6)FCLR 功能:浮点数清零

入口条件:操作数在[R0]中。

出口信息:操作数被清零。

影响资源:A 堆栈需求: 2字节

FCLR:   INC R0
        INC R0
        CLR A
        MOV @R0,A
        DEC R0
        MOV @R0,A
        DEC R0
        MOV @R0,#41H
        RET

(7)FZER 功能:浮点数判零

入口条件:操作数在[R0]中。

出口信息:若累加器A为零,则操作数[R0]为零,否则不为零。

影响资源:A 堆栈需求: 2字节

FZER:   INC R0
        INC R0
        MOV A,@R0
        DEC R0
        ORL A,@R0
        DEC R0
        JNZ ZERO
        MOV @R0,#41H
ZERO:   RET

(8)FMOV 功能:浮点数传送

入口条件:源操作数在[R1]中,目标地址为[R0]。

出口信息:[R0]=[R1],[R1]不变。

影响资源:A 堆栈需求: 2字节

FMOV:   INC R0
        INC R0
        INC R1
        INC R1
        MOV A,@R1
        MOV @R0,A
        DEC R0
        DEC R1
        MOV A,@R1
        MOV @R0,A
        DEC R0
        DEC R1
        MOV A,@R1
        MOV @R0,A
        RET

(9)FPUS 功能:浮点数压栈

入口条件:操作数在[R0]中。

出口信息:操作数压入栈顶。

影响资源:A、R2、R3 堆栈需求: 5字节

FPUS:   POP ACC        ;将返回地址保存在R2R3中
        MOV R2,A
        POP ACC
        MOV R3,A
        MOV A,@R0      ;将操作数压入堆栈
        PUSH ACC
        INC R0
        MOV A,@R0
        PUSH ACC
        INC R0
        MOV A,@R0
        PUSH ACC
        DEC R0
        DEC R0
        MOV A,R3       ;将返回地址压入堆栈
        PUSH ACC
        MOV A,R2
        PUSH ACC
        RET            ;返回主程序

(10)FPOP 功能:浮点数出栈

入口条件:操作数处于栈顶。

出口信息:操作数弹至[R0]中。

影响资源:A、R2、R3 堆栈需求: 2字节

FPOP:   POP ACC        ;将返回地址保存在R2R3中
        MOV R2,A
        POP ACC
        MOV R3,A
        INC R0
        INC R0
        POP ACC        ;将操作数弹出堆栈,传送到[R0]中
        MOV @R0,A
        DEC R0
        POP ACC
        MOV @R0,A
        DEC R0
        POP ACC
        MOV @R0,A
        MOV A,R3       ;将返回地址压入堆栈
        PUSH ACC
        MOV A,R2
        PUSH ACC
        RET            ;返回主程序

(11)FCMP 功能:浮点数代数值比较(不影响待比较操作数)

入口条件:待比较操作数分别在[R0]和[R1]中。

出口信息:若CY=1,则[R0] < [R1],若CY=0且A=0则 [R0] = [R1],否则[R0] > [R1]。

影响资源:A、B、PSW 堆栈需求: 2字节

FCMP:   MOV A,@R0      ;数符比较
        XRL A,@R1
        JNB ACC.7,CMP2
        MOV A,@R0      ;两数异号,以[R0]数符为准
        RLC A
        MOV A,#0FFH
        RET
CMP2:   MOV A,@R1      ;两数同号,准备比较阶码
        MOV C,ACC.6
        MOV ACC.7,C
        MOV B,A
        MOV A,@R0
        MOV C,ACC.7
        MOV F0,C       ;保存[R0]的数符
        MOV C,ACC.6
        MOV ACC.7,C
        CLR C          ;比较阶码
        SUBB A,B
        JZ CMP6
        RLC A          ;取阶码之差的符号
        JNB F0,CMP5
        CPL C          ;[R0]为负时,结果取反
CMP5:   MOV A,#0FFH    ;两数不相等
        RET
CMP6:   INC R0         ;阶码相同时,准备比较尾数
        INC R0
        INC R1
        INC R1
        CLR C
        MOV A,@R0
        SUBB A,@R1
        MOV B,A        ;保存部分差
        DEC R0
        DEC R1
        MOV A,@R0
        SUBB A,@R1
        DEC R0
        DEC R1
        ORL A,B        ;生成是否相等信息
        JZ CMP7
        JNB F0,CMP7
        CPL C          ;[R0]为负时,结果取反
CMP7:   RET

(12) 标号:FABS 功能:浮点绝对值函数

入口条件:   操作数在[R0]中。

出口信息:   结果仍在[R0]中。

影响资源:   A 堆栈需求: 2字节

FABS:   MOV A,@R0      ;读取操作数的阶码
        CLR ACC.7      ;清除数符
        MOV @R0,A      ;回传阶码
        RET

(13)FSGN 功能:浮点符号函数

入口条件:操作数在[R0]中。

出口信息:累加器 A=1 时为正数,A=0FFH时为负数,A=0 时为零。

影响资源:PSW、A 堆栈需求: 2字节

FSGN:   INC R0         ;读尾数
        MOV A,@R0
        INC R0
        ORL A,@R0
        DEC R0
        DEC R0
        JNZ SGN
        RET            ;尾数为零,结束
SGN:    MOV A,@R0      ;读取操作数的阶码
        RLC A          ;取数符
        MOV A,#1       ;按正数初始化
        JNC SGN1       ;是正数,结束
        MOV A,#0FFH    ;是负数,改变标志
SGN1:   RET

(14)FINT 功能:浮点取整函数

入口条件:操作数在[R0]中。

出口信息:结果仍在[R0]中。

影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节

FINT:   LCALL MVR0     ;将[R0]传送到第一工作区中
        LCALL INT      ;在工作寄存器中完成取整运算
        LJMP MOV0      ;将结果传回到[R0]中
INT:    MOV A,R3
        ORL A,R4
        JNZ INTA
        CLR 1FH        ;尾数为零,阶码也清零,结束取整
        MOV R2,#41H
        RET
INTA:   MOV A,R2
        JZ INTB        ;阶码为零否?
        JB ACC.7,INTB  ;阶符为负否?
        CLR C
        SUBB A,#10H    ;阶码小于16否?
        JC INTD
        RET            ;阶码大于16,已经是整数
INTB:   CLR A          ;绝对值小于一,取整后正数为零,负数为负一
        MOV R4,A
        MOV C,1FH
        RRC A
        MOV R3,A
        RL A
        MOV R2,A
        JNZ INTC
        MOV R2,#41H
INTC:   RET
INTD:   CLR F0         ;舍尾标志初始化
INTE:   CLR C
        LCALL RR1      ;右规一次
        ORL C,F0       ;记忆舍尾情况
        MOV F0,C
        CJNE R2,#10H,INTE      ;阶码达到16(尾数完全为整数)否?
        JNB F0,INTF    ;舍去部分为零否?
        JNB 1FH,INTF   ;操作数为正数否?
        INC R4         ;对于带小数的负数,向下取整
        MOV A,R4
        JNZ INTF
        INC R3
INTF:   LJMP RLN       ;将结果规格化

(15)FRCP 功能:浮点倒数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 5字节

FRCP:   MOV A,@R0
        MOV C,ACC.7
        MOV 1FH,C      ;保存数符
        MOV C,ACC.6    ;绝对值传送到第二工作区
        MOV ACC.7,C
        MOV R5,A
        INC R0
        MOV A,@R0
        MOV R6,A
        INC R0
        MOV A,@R0
        MOV R7,A
        DEC R0
        DEC R0
        ORL A,R6
        JNZ RCP
        SETB OV        ;零不能求倒数,设立溢出标志
        RET
RCP:    MOV A,R6
        JB ACC.7,RCP2  ;操作数格式化否?
        CLR C          ;格式化之
        MOV A,R7
        RLC A
        MOV R7,A
        MOV A,R6
        RLC A
        MOV R6,A
        DEC R5
        SJMP RCP
RCP2:   MOV R2,#1      ;将数值1.00传送到第一工作区
        MOV R3,#80H
        MOV R4,#0
        LCALL DIV3     ;调用工作区浮点除法,求得倒数
        LJMP MOV0      ;回传结果

(16)FSQU 功能:浮点数平方

入口条件:操作数在[R0]中。

出口信息:OV=0时,平方值仍然在[R0]中,OV=1时溢出。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 9字节

FSQU:   MOV A,R0       ;将操作数
        XCH A,R1       ;同时作为乘数
        PUSH ACC       ;保存R1指针
        LCALL FMUL     ;进行乘法运算
        POP ACC
        MOV R1,A       ;恢复R1指针
        RET

(17)FSQR 功能:浮点数开平方(快速逼近算法)

入口条件:操作数在[R0]中。

出口信息:OV=0时,平方根仍在[R0]中,OV=1时,负数开平方出错。

影响资源:PSW、A、B、R2~R7 堆栈需求: 2字节

FSQR:   MOV A,@R0
        JNB ACC.7,SQR
        SETB OV        ;负数开平方,出错
        RET
SQR:    INC R0
        INC R0
        MOV A,@R0
        DEC R0
        ORL A,@R0
        DEC R0
        JNZ SQ
        MOV @R0,#41H   ;尾数为零,不必运算
        CLR OV
        RET
SQ:     MOV A,@R0
        MOV C,ACC.6    ;将阶码扩展成8bit补码
        MOV ACC.7,C
        INC A          ;加一
        CLR C
        RRC A          ;除二
        MOV @R0,A      ;得到平方根的阶码,回存之
        INC R0         ;指向被开方数尾数的高字节
        JC SQR0        ;原被开方数的阶码是奇数吗?
        MOV A,@R0      ;是奇数,尾数右规一次
        RRC A
        MOV @R0,A
        INC R0
        MOV A,@R0
        RRC A
        MOV @R0,A
        DEC R0
SQR0:   MOV A,@R0
        JZ SQR9        ;尾数为零,不必运算
        MOV R2,A       ;将尾数传送到R2R3中
        INC R0
        MOV A,@R0
        MOV R3,A
        MOV A,R2       ;快速开方,参阅定点子程序说明
        ADD A,#57H
        JC SQR2
        ADD A,#45H
        JC SQR1
        ADD A,#24H
        MOV B,#0E3H
        MOV R4,#80H
        SJMP SQR3
SQR1:   MOV B,#0B2H
        MOV R4,#0A0H
        SJMP SQR3
SQR2:   MOV B,#8DH
        MOV R4,#0D0H
SQR3:   MUL AB
        MOV A,B
        ADD A,R4
        MOV R4,A
        MOV B,A
        MUL AB
        XCH A,R3
        CLR C
        SUBB A,R3
        MOV R3,A
        MOV A,B
        XCH A,R2
        SUBB A,R2
        MOV R2,A
SQR4:   SETB C
        MOV A,R4
        RLC A
        MOV R6,A
        CLR A
        RLC A
        MOV R5,A
        MOV A,R3
        SUBB A,R6
        MOV B,A
        MOV A,R2
        SUBB A,R5
        JC SQR5
        INC R4
        MOV R2,A
        MOV R3,B
        SJMP SQR4
SQR5:   MOV A,R4
        XCH A,R2
        RRC A
        MOV F0,C
        MOV A,R3
        MOV R5,A
        MOV R4,#8
SQR6:   CLR C
        MOV A,R3
        RLC A
        MOV R3,A
        CLR C
        MOV A,R5
        SUBB A,R2
        JB F0,SQR7
        JC SQR8
SQR7:   MOV R5,A
        INC R3
SQR8:   CLR C
        MOV A,R5
        RLC A
        MOV R5,A
        MOV F0,C
        DJNZ R4,SQR6
        MOV A,R3       ;将平方根的尾数回传到[R0]中
        MOV @R0,A
        DEC R0
        MOV A,R2
        MOV @R0,A
SQR9:   DEC R0         ;数据指针回归原位
        CLR OV         ;开方结果有效
        RET

(18)FPLN 功能:浮点数多项式计算

入口条件:自变量在[R0]中,多项式系数在调用指令之后,以40H结束。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 4字节

FPLN:   POP DPH        ;取出多项式系数存放地址
        POP DPL
        XCH A,R0       ;R0、R1交换角色,自变量在[R1]中
        XCH A,R1
        XCH A,R0
        CLR A          ;清第一工作区
        MOV R2,A
        MOV R3,A
        MOV R4,A
        CLR 1FH
PLN1:   CLR A          ;读取一个系数,并装入第二工作区
        MOVC A,@A+DPTR
        MOV C,ACC.7
        MOV 1EH,C
        MOV C,ACC.6
        MOV ACC.7,C
        MOV R5,A
        INC DPTR
        CLR A
        MOVC A,@A+DPTR
        MOV R6,A
        INC DPTR
        CLR A
        MOVC A,@A+DPTR
        MOV R7,A
        INC DPTR       ;指向下一个系数
        MOV C,1EH      ;比较两个数符
        RRC A
        XRL A,23H
        RLC A
        MOV F0,C       ;保存比较结果
        LCALL AS1      ;进行代数加法运算
        CLR A          ;读取下一个系数的第一个字节
        MOVC A,@A+DPTR
        CJNE A,#40H,PLN2       ;是结束标志吗?
        XCH A,R0       ;运算结束,恢复R0、R1原来的角色
        XCH A,R1
        XCH A,R0
        LCALL MOV0     ;将结果回传到[R0]中
        CLR A
        INC DPTR
        JMP @A+DPTR    ;返回主程序
PLN2:   MOV A,@R1      ;比较自变量和中间结果的符号
        XRL A,23H
        RLC A
        MOV 1FH,C      ;保存比较结果
        LCALL MUL0     ;进行乘法运算
        SJMP PLN1      ;继续下一项运算

(19)FLOG 功能:以10为底的浮点对数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,负数或零求对数出错。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:9字节

FLOG:   LCALL FLN      ;先以e为底求对数
        JNB OV,LOG
        RET            ;如溢出则停止计算
LOG:    MOV R5,#0FFH   ;系数0.43430(1/Ln10)
        MOV R6,#0DEH
        MOV R7,#5CH
        LCALL MUL1     ;通过相乘来换底
        LJMP MOV0      ;传回结果

(20)FLN 功能:以e为底的浮点对数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,负数或零求对数出错。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求: 7字节

FLN:    LCALL MVR0     ;将[R0]传送到第一工作区
        JB 1FH,LNOV    ;负数或零求对数,出错
        MOV A,R3
        ORL A,R4
        JNZ LN0
LNOV:   SETB OV
        RET
LN0:    CLR C
        LCALL RL1      ;左规一次
        CLR A
        XCH A,R2       ;保存原阶码,清零工作区的阶码
        PUSH ACC
        LCALL RLN      ;规格化
        LCALL MOV0     ;回传
        LCALL FPLN     ;用多项式计算尾数的对数
        DB 7BH,0F4H,30H;0.029808
        DB 0FEH,85H,13H;-0.12996
        DB 7FH,91H,51H ;0.28382
        DB 0FFH,0FAH,0BAH      ;-0.4897
        DB 0,0FFH,0CAH ;0.99918
        DB 70H,0C0H,0  ;1.1442×10-5
        DB 40H         ;结束
        POP ACC        ;取出原阶码
        JNZ LN1
        RET            ;如为零,则结束
LN1:    CLR 1EH        ;清第二区数符
        MOV C,ACC.7
        MOV F0,C       ;保存阶符
        JNC LN2
        CPL A          ;当阶码为负时,求其绝对值
        INC A
LN2:    MOV R2,A       ;阶码的绝对值乘以0.69315
        MOV B,#72H
        MUL AB
        XCH A,R2
        MOV R7,B
        MOV B,#0B1H
        MUL AB
        ADD A,R7
        MOV R7,A       ;乘积的尾数在R6R7R2中
        CLR A
        ADDC A,B
        MOV R6,A
        MOV R5,#8      ;乘积的阶码初始化(整数部分为一字节)
LN3:    JB ACC.7,LN4   ;乘积格式化
        MOV A,R2
        RLC A
        MOV R2,A
        MOV A,R7
        RLC A
        MOV R7,A
        MOV A,R6
        RLC A
        MOV R6,A
        DEC R5
        SJMP LN3
LN4:    MOV C,F0       ;取出阶符,作为乘积的数符
        MOV ACC.7,C

LJMP ASN ;与尾数的对数合并,得原操作数的对数

(21)FE10 功能:以10为底的浮点指数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

FE10:   MOV R5,#2      ;加权系数为3.3219(Log210)
        MOV R6,#0D4H
        MOV R7,#9AH
        SJMP EXP       ;先进行加权运算,后以2为底统一求幂

(22)FEXP 功能:以e为底的浮点指数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

FEXP:   MOV R5,#1      ;加权系数为1.44272(Lng2e)
        MOV R6,#0B8H
        MOV R7,#0ABH
EXP:    CLR 1EH        ;加权系数为正数
        LCALL MVR0     ;将[R0]传送到第一工作区
        LCALL MUL1     ;进行加权运算
        SJMP E20       ;以2为底统一求幂

(23)FE2 功能:以2为底的浮点指数函数

入口条件:操作数在[R0]中。

出口信息:OV=0时,结果仍在[R0]中,OV=1时,溢出。

影响资源:DPTR、PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

FE2:    LCALL MVR0     ;将[R0]传送到第一工作区
E20:    MOV A,R3
        ORL A,R4
        JZ EXP1        ;尾数为零
        MOV A,R2
        JB ACC.7,EXP2  ;阶符为负?
        SETB C
        SUBB A,#6      ;阶码大于6否?
        JC EXP2
        JB 1FH,EXP0    ;数符为负否?
        MOV @R0,#3FH   ;正指数过大,幂溢出
        INC R0
        MOV @R0,#0FFH
        INC R0
        MOV @R0,#0FFH
        DEC R0
        DEC R0
        SETB OV
        RET
EXP0:   MOV @R0,#41H   ;负指数过大,幂下溢,清零处理
        CLR A
        INC R0
        MOV @R0,A
        INC R0
        MOV @R0,A
        DEC R0
        DEC R0
        CLR OV
        RET
EXP1:   MOV @R0,#1     ;指数为零,幂为1.00
        INC R0
        MOV @R0,#80H
        INC R0
        MOV @R0,#0
        DEC R0
        DEC R0
        CLR OV
        RET
EXP2:   MOV A,R2       ;将指数复制到第二工作区
        MOV R5,A
        MOV A,R3
        MOV R6,A
        MOV A,R4
        MOV R7,A
        MOV C,1FH
        MOV 1EH,C
        LCALL INT      ;对第一区取整
        MOV A,R3
        JZ EXP4
EXP3:   CLR C          ;使尾数高字节R3对应一个字节整数
        RRC A
        INC R2
        CJNE R2,#8,EXP3
EXP4:   MOV R3,A
        JNB 1FH,EXP5
        CPL A          ;并用补码表示
        INC A
EXP5:   PUSH ACC       ;暂时保存之
        LCALL RLN      ;重新规格化
        CPL 1FH
        SETB F0
        LCALL AS1      ;求指数的小数部分
        LCALL MOV0     ;回传指数的小数部分
        LCALL FPLN     ;通过多项式计算指数的小数部分的幂
        DB 77H,0B1H,0C9H       ;1.3564×10-3
        DB 7AH,0A1H,68H;9.8514×10-3
        DB 7CH,0E3H,4FH;0.055495
        DB 7EH,0F5H,0E7H       ;0.24014
        DB 0,0B1H,72H  ;0.69315
        DB 1,80H,0     ;1.00000
        DB 40H         ;结束
        POP ACC        ;取出指数的整数部分
        ADD A,R2       ;按补码加到幂的阶码上
        MOV R2,A
        CLR 1FH        ;幂的符号为正
        LJMP MOV0      ;将幂传回[R0]中

(24)标号: DTOF 功能:双字节十六进制定点数转换成格式化浮点数

入口条件:双字节定点数的绝对值在[R0]中,数符在位1FH中,整数部分的位数在A中。

出口信息:转换成格式化浮点数在[R0]中(三字节)。

影响资源:PSW、A、R2、R3、R4、位1FH 堆栈需求: 6字节

DTOF:   MOV R2,A       ;按整数的位数初始化阶码
        MOV A,@R0      ;将定点数作尾数
        MOV R3,A
        INC R0
        MOV A,@R0
        MOV R4,A
        DEC R0
        LCALL RLN      ;进行规格化
        LJMP MOV0      ;传送结果到[R0]中

(25)FTOD 功能:格式化浮点数转换成双字节定点数

入口条件:格式化浮点操作数在[R0]中。

出口信息:OV=1时溢出,OV=0时转换成功:定点数的绝对值在[R0]中(双字节),数符

在位1FH中,F0=1 时为整数,CY=1时为一字节整数一字节小数,否则为纯小数。

影响资源:PSW、A、B、R2、R3、R4、位1FH 堆栈需求: 6字节

FTOD:   LCALL MVR0     ;将[R0]传送到第一工作区
        MOV A,R2
        JZ FTD4        ;阶码为零,纯小数
        JB ACC.7,FTD4  ;阶码为负,纯小数
        SETB C
        SUBB A,#10H
        JC FTD1
        SETB OV        ;阶码大于16,溢出
        RET
FTD1:   SETB C
        MOV A,R2
        SUBB A,#8      ;阶码大于8否?
        JC FTD3
FTD2:   MOV B,#10H     ;阶码大于8,按双字节整数转换
        LCALL FTD8
        SETB F0        ;设立双字节整数标志
        CLR C
        CLR OV
        RET
FTD3:   MOV B,#8       ;按一字节整数一字节小数转换
        LCALL FTD8
        SETB C         ;设立一字节整数一字节小数标志
        CLR F0
        CLR OV
        RET
FTD4:   MOV B,#0       ;按纯小数转换
        LCALL FTD8
        CLR OV         ;设立纯小数标志
        CLR F0
        CLR C
        RET
FTD8:   MOV A,R2       ;按规定的整数位数进行右规
        CJNE A,B,FTD9
        MOV A,R3       ;将双字节结果传送到[R0]中
        MOV @R0,A
        INC R0
        MOV A,R4
        MOV @R0,A
        DEC R0
        RET
FTD9:   CLR C
        LCALL RR1      ;右规一次
        SJMP FTD8

(26)BTOF 功能:浮点BCD码转换成格式化浮点数

入口条件:浮点BCD码操作数在[R0]中。

出口信息:转换成的格式化浮点数仍在[R0]中。

影响资源:PSW、A、B、R2~R7、位1DH~1FH 堆栈需求:6字节

BTOF:   INC R0         ;判断是否为零。
        INC R0
        MOV A,@R0
        MOV R7,A
        DEC R0
        MOV A,@R0
        MOV R6,A
        DEC R0
        ORL A,R7
        JNZ BTF0
        MOV @R0,#41H   ;为零,转换结束。
        RET
BTF0:   MOV A,@R0
        MOV C,ACC.7
        MOV 1DH,C      ;保存数符。
        CLR 1FH        ;以绝对值进行转换。
        MOV C,ACC.6    ;扩充阶码为八位。
        MOV ACC.7,C
        MOV @R0,A
        JNC BTF1
        ADD A,#19      ;是否小于1E-19?
        JC BTF2
        MOV @R0,#41H   ;小于1E-19时以0计。
        INC R0
        MOV @R0,#0
        INC R0
        MOV @R0,#0
        DEC R0
        DEC R0
        RET
BTF1:   SUBB A,#19
        JC BTF2
        MOV A,#3FH     ;大于1E19时封顶。
        MOV C,1DH
        MOV ACC.7,C
        MOV @R0,A
        INC R0
        MOV @R0,#0FFH
        INC R0
        MOV @R0,#0FFH
        DEC R0
        DEC R0
        RET
BTF2:   CLR A          ;准备将BCD码尾数转换成十六进制浮点数。
        MOV R4,A
        MOV R3,A
        MOV R2,#10H    ;至少两个字节。
BTF3:   MOV A,R7
        ADD A,R7
        DA A
        MOV R7,A
        MOV A,R6
        ADDC A,R6
        DA A
        MOV R6,A
        MOV A,R4
        RLC A
        MOV R4,A
        MOV A,R3
        RLC A
        MOV R3,A
        DEC R2
        JNB ACC.7,BTF3 ;直到尾数规格化。
        MOV A,R6       ;四舍五入。
        ADD A,#0B0H
        CLR A
        ADDC A,R4
        MOV R4,A
        CLR A
        ADDC A,R3
        MOV R3,A
        JNC BTF4
        MOV R3,#80H
        INC R2
BTF4:   MOV DPTR,#BTFL ;准备查表得到十进制阶码对应的浮点数。
        MOV A,@R0
        ADD A,#19      ;计算表格偏移量。
        MOV B,#3
        MUL AB
        ADD A,DPL
        MOV DPL,A
        JNC BTF5
        INC DPH
BTF5:   CLR A          ;查表。
        MOVC A,@A+DPTR
        MOV C,ACC.6
        MOV ACC.7,C
        MOV R5,A
        MOV A,#1
        MOVC A,@A+DPTR
        MOV R6,A
        MOV A,#2
        MOVC A,@A+DPTR
        MOV R7,A
        LCALL MUL1     ;将阶码对应的浮点数和尾数对应的浮点数相乘。
        MOV C,1DH      ;取出数符。
        MOV 1FH,C
        LJMP MOV0      ;传送转换结果。

(27)FTOB 功能:格式化浮点数转换成浮点BCD码

入口条件:格式化浮点操作数在[R0]中。

出口信息:转换成的浮点BCD码仍在[R0]中。

影响资源:PSW、A、B、R2~R7、位1DH~1FH 堆栈需求:6字节

FTOB:   INC R0
        MOV A,@R0
        INC R0
        ORL A,@R0
        DEC R0
        DEC R0
        JNZ FTB0
        MOV @R0,#41H
        RET
FTB0:   MOV A,@R0
        MOV C,ACC.7
        MOV 1DH,C
        CLR ACC.7
        MOV @R0,A
        LCALL MVR0
        MOV DPTR,#BFL0 ;绝对值大于或等于1时的查表起点。
        MOV B,#0       ;十的0次幂。
        MOV A,R2
        JNB ACC.7,FTB1
        MOV DPTR,#BTFL ;绝对值小于1E-6时的查表起点。
        MOV B,#0EDH    ;十的-19次幂。
        ADD A,#16
        JNC FTB1
        MOV DPTR,#BFLN ;绝对值大于或等于1E-6时的查表起点。
        MOV B,#0FAH    ;十的-6次幂。
FTB1:   CLR A          ;查表,找到一个比待转换浮点数大的整数幂。
        MOVC A,@A+DPTR
        MOV C,ACC.6
        MOV ACC.7,C
        MOV R5,A
        MOV A,#1
        MOVC A,@A+DPTR
        MOV R6,A
        MOV A,#2
        MOVC A,@A+DPTR
        MOV R7,A
        MOV A,R5       ;和待转换浮点数比较。
        CLR C
        SUBB A,R2
        JB ACC.7,FTB2  ;差为负数。
        JNZ FTB3
        MOV A,R6
        CLR C
        SUBB A,R3
        JC FTB2
        JNZ FTB3
        MOV A,R7
        CLR C
        SUBB A,R4
        JC FTB2
        JNZ FTB3
        MOV R5,B       ;正好是表格中的数。
        INC R5         ;幂加一。
        MOV R6,#10H    ;尾数为0•1000。
        MOV R7,#0
        SJMP FTB6      ;传送转换结果。
FTB2:   INC DPTR       ;准备表格下一项。
        INC DPTR
        INC DPTR
        INC B          ;幂加一。
        SJMP FTB1
FTB3:   PUSH B         ;保存幂值。
        LCALL DIV3     ;相除,得到一个二进制浮点数的纯小数。
FTB4:   MOV A,R2       ;取阶码。
        JZ FTB5        ;为零吗?
        CLR C
        LCALL RR1      ;右规。
        SJMP FTB4
FTB5:   POP ACC        ;取出幂值。
        MOV R5,A       ;作为十进制浮点数的阶码。
        LCALL HB2      ;转换尾数的十分位和百分位。
        MOV R6,A
        LCALL HB2      ;转换尾数的千分位和万分位。
        MOV R7,A
        MOV A,R3       ;四舍五入。
        RLC A
        CLR A
        ADDC A,R7
        DA A
        MOV R7,A
        CLR A
        ADDC A,R6
        DA A
        MOV R6,A
        JNC FTB6
        MOV R6,#10H
        INC R5
FTB6:   INC R0         ;存放转换结果。
        INC R0
        MOV A,R7
        MOV @R0,A
        DEC R0
        MOV A,R6
        MOV @R0,A
        DEC R0
        MOV A,R5
        MOV C,1DH      ;取出数符。
        MOV ACC.7,C
        MOV @R0,A
        RET
HB2:    MOV A,R4       ;尾数扩大100倍。
        MOV B,#100
        MUL AB
        MOV R4,A
        MOV A,B
        XCH A,R3
        MOV B,#100
        MUL AB
        ADD A,R3
        MOV R3,A
        JNC HB21
        INC B
HB21:   MOV A,B        ;将整数部分转换成BCD码。
        MOV B,#10
        DIV AB
        SWAP A
        ORL A,B
        RET
BTFL:   DB 41H,0ECH,1EH;1.0000E-19
        DB 45H,93H,93H ;1.0000E-18
        DB 48H,0B8H,78H;1.0000E-17
        DB 4BH,0E6H,96H;1.0000E-16
        DB 4FH,90H,1DH ;1.0000E-15
        DB 52H,0B4H,25H;1.0000E-14
        DB 55H,0E1H,2EH;1.0000E-13
        DB 59H,8CH,0BDH;1.0000E-12
        DB 5CH,0AFH,0ECH       ;1.0000E-11
        DB 5FH,0DBH,0E7H       ;1.0000E-10
        DB 63H,89H,70H ;1.0000E-9
        DB 66H,0ABH,0CCH       ;1.0000E-8
        DB 69H,0D6H,0C0H       ;1.0000E-7
BFLN:   DB 6DH,86H,38H ;1.0000E-6
        DB 70H,0A7H,0C6H       ;1.0000E-5
        DB 73H,0D1H,0B7H       ;1.0000E-4
        DB 77H,83H,12H ;1.0000E-3
        DB 7AH,0A3H,0D7H       ;1.0000E-2
        DB 7DH,0CCH,0CDH       ;1.0000E-1
BFL0:   DB 1,80H,00H   ;1.0000
        DB 4,0A0H,00H  ;1.0000E1
        DB 7,0C8H,00H  ;1.0000E2
        DB 0AH,0FAH,00H;1.0000E3
        DB 0EH,9CH,40H ;1.0000E4
        DB 11H,0C3H,50H;1.0000E5
        DB 14H,0F4H,24H;1.0000E6
        DB 18H,98H,97H ;1.0000E7
        DB 1BH,0BEH,0BCH       ;1.0000E8
        DB 1EH,0EEH,6BH;1.0000E9
        DB 22H,95H,03H ;1.0000E10
        DB 25H,0BAH,44H;1.0000E11
        DB 28H,0E8H,0D5H       ;1.0000E12
        DB 2CH,91H,85H ;1.0000E13
        DB 2FH,0B5H,0E6H       ;1.0000E14
        DB 32H,0E3H,60H;1.0000E15
        DB 36H,8EH,1CH ;1.0000E16
        DB 39H,31H,0A3H;1.0000E17
        DB 3CH,0DEH,0BH;1.0000E18
        DB 40H,8AH,0C7H;1.0000E19

(28)FCOS 功能:浮点余弦函数

入口条件:操作数在[R0]中。

出口信息:结果仍在[R0]中。

影响资源:DPTR、PSW、A、B、R2~R7、位1DH~1FH 堆栈需求: 6字节

FCOS:   LCALL FABS     ;COS(-X) = COS X
        MOV R5,#1      ;常数1.5708(π/2)
        MOV R6,#0C9H
        MOV R7,#10H
        CLR 1EH
        LCALL MVR0
        CLR F0
        LCALL AS1      ;x+(π/2)
        LCALL MOV0     ;保存结果,接着运行下面的FSIN程序

(29)FSIN 功能:浮点正弦函数

入口条件:操作数在[R0]中。

出口信息:结果仍在[R0]中。

影响资源:DPTR、PSW、A、B、R2~R7、位1DH~1FH 堆栈需求: 6字节

FSIN:   MOV A,@R0
        MOV C,ACC.7
        MOV 1DH,C      ;保存自变量的符号
        CLR ACC.7      ;统一按正数计算
        MOV @R0,A
        LCALL MVR0     ;将[R0]传送到第一工作区
        MOV R5,#0      ;系数0.636627(2/π)
        MOV R6,#0A2H
        MOV R7,#0FAH
        CLR 1EH
        LCALL MUL1     ;相乘,自变量按(π/2)规一化
        MOV A,R2       ;将结果复制到第二区
        MOV R5,A
        MOV A,R3
        MOV R6,A
        MOV A,R4
        MOV R7,A
        LCALL INT      ;第一区取整,获得象限信息
        MOV A,R2
        JZ SIN2
SIN1:   CLR C          ;将浮点象限数转换成定点象限数
        LCALL RR1
        CJNE R2,#10H,SIN1
        MOV A,R4
        JNB ACC.1,SIN2
        CPL 1DH        ;对于第三、四象限,结果取反
SIN2:   JB ACC.0,SIN3
        CPL 1FH        ;对于第一、三象限,直接求规一化的小数
        SJMP SIN4
SIN3:   MOV A,R4       ;对于第二、四象限,准备求其补数
        INC A
        MOV R4,A
        JNZ SIN4
        INC R3
SIN4:   LCALL RLN      ;规格化
        SETB F0
        LCALL AS1      ;求自变量归一化等效值
        LCALL MOV0     ;回传
        LCALL FPLN     ;用多项式计算正弦值
        DB 7DH,93H,28H ;0.07185
        DB 41H,0,0     ;0
        DB 80H,0A4H,64H;-0.64215
        DB 41H,0,0     ;0
        DB 1,0C9H,2    ;1.5704
        DB 41H,0,0     ;0
        DB 40H         ;结束
        MOV A,@R0      ;结果的绝对值超过1.00吗?
        JZ SIN5
        JB ACC.6,SIN5
        INC R0         ;绝对值按1.00封顶
        MOV @R0,#80H
        INC R0
        MOV @R0,#0
        DEC R0
        DEC R0
        MOV A,#1
SIN5:   MOV C,1DH      ;将数符拼入结果中
        MOV ACC.7,C
        MOV @R0,A
        RET

(30)FATN 功能:浮点反正切函数

入口条件:操作数在[R0]中。

出口信息:结果仍在[R0]中。

影响资源:DPTR、PSW、A、B、R2~R7、位1CH~1FH 堆栈需求:7字节

FATN:   MOV A,@R0
        MOV C,ACC.7
        MOV 1DH,C      ;保存自变量数符
        CLR ACC.7      ;自变量取绝对值
        MOV @R0,A
        CLR 1CH        ;清求余运算标志
        JB ACC.6,ATN1  ;自变量为纯小数否?
        JZ ATN1
        SETB 1CH       ;置位求余运算标志
        LCALL FRCP     ;通过倒数运算,转换成纯小数
ATN1:   LCALL FPLN     ;通过多项式运算,计算反正切函数值
        DB 0FCH,0E4H,91H       ;-0.055802
        DB 7FH,8FH,37H ;0.27922
        DB 0FFH,0EDH,0E0H      ;-0.46460
        DB 7BH,0E8H,77H;0.028377
        DB 0,0FFH,68H  ;0.9977
        DB 72H,85H,0ECH;3.1930×10-5
        DB 40H         ;结束
        JNB 1CH,ATN2   ;需要求余运算否?
        CPL 1FH        ;准备运算标志
        MOV C,1FH
        MOV F0,C       ;常数1.5708(π/2)
        MOV R5,#1
        MOV R6,#0C9H
        MOV R7,#10H
        LCALL AS1      ;求余运算
        LCALL MOV0     ;回传
ATN2:   MOV A,@R0      ;拼入结果的数符
        MOV C,1DH
        MOV ACC.7,C
        MOV @R0,A
        RET

(31)RTOD 功能:浮点弧度数转换成浮点度数

入口条件:浮点弧度数在[R0]中。

出口信息:转换成的浮点度数仍在[R0]中。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

RTOD:   MOV R5,#6      ;系数(180/π)传送到第二工作区
        MOV R6,#0E5H
        MOV R7,#2FH
        SJMP DR        ;通过乘法进行转换

(32)DTOR 功能:浮点度数转换成浮点弧度数

入口条件:浮点度数在[R0]中。

出口信息:转换成的浮点弧度数仍在[R0]中。

影响资源:PSW、A、B、R2~R7、位1EH、1FH 堆栈需求:6字节

DTOR:   MOV R5,#0FBH   ;系数(π/180)传送到第二工作区
        MOV R6,#8EH
        MOV R7,#0FAH
DR:     LCALL MVR0     ;将[R0]传送到第一工作区
        CLR 1EH        ;系数为正
        LCALL MUL1     ;通过乘法进行转换
        LJMP MOV0      ;结果传送到[R0]中
        END


可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号