📄 zz51.a51
字号:
;* =========================================================================== *
;* 华信单片机工作室 卢先生 http://www.hx51.com/
;* 整理验证日期: 2003/12/04, 更新日期:2005/08/01
;------------------------------------------------------------------------------
;* 标题:MCS-51单片机浮点子程序库,程序名:ZZ51.A51
;* 描述:
;* 以下浮点数格式与标准的IEEE浮点数格式不尽相同,是IEEE-754标准的变异型,称作为IEEE-754_2型。
;* 说明详见本站文章:《浮点数转换器》
;* 参考资料:《MCS-51/196单片机浮点数程序和实用程序》一书
;------------------------------------------------------------------------------
;* 二进制浮点数格式的定义:
地址 eb BY0 BY1 BY2
内容 PtEEEEEEE S.MMMMMMM MMMMMMMM MMMMMMMM
; Pt 代表阶符,阶符视阶的正负而定;
; S 代表符号(数符)位1是负,0是正;
; . 小数点在数符的右边;
; E 代表幂偏移,即指数偏差;
; M 24位的尾数保存在23位中,只存储23位,隐含最高位1。
; 阶码采用1字节移码,以80H~0FFH表示0~127,以01H~7FH表示-127~-1。
; 阶码的计算方法:
; (1)十进制整数(可带小数):
; 阶码eb=指数P+80H
; 其中:指数P=int(Z)+1,Z=ln(A)/ln(2)
;(2)纯小数:
; 阶码eb=指数+80H
; 其中:指数P=int(Z),Z=ln(A)/ln(2)
; 能表示的数据范围为:5.8×10^(-39)~1.7×10^38,超出范围为溢出。
;------------------------------------------------------------------------------
;* 十进制浮点数(浮点BCD码)中阶符、数符、阶的定义:
;* 阶符: 正为00H,负为0FFH
;* 数符: 正数为00H,负数为0FFH
;* 阶: 这里所说的阶是十进制浮点数的阶,即为小数点的位置.
;* 如 0.1的阶为'0'; 0.01的阶为'-1'; 1的阶为'+1'; 22.00的阶为'+2'
;* 阶码=阶+80H, 其中80H为指数的偏移量
;* 阶与尾数均为压缩BCD码,尾数为纯小数
;* 例子 将十进数 50.265 放入相应的单元
;* 标号: DTOB 功能: 将十进制浮点数转成二进制浮点数
;* 入口: 十进制浮点数在R1,R2,R3,R4,R5,R6,R7单元内,
;* 十进制数阶符 R1=00H, 十进制数数符 R2=00H, 十进制数阶 R3=02H,
;* 尾数 R4=50H, R5=26H, R6=50H, R7=00H
;* 出口:(R4)=86H,(R5)=49H,(R6)=0FH,(R4)=5DH
;----------------------------------------------------------
;* 说明:凡查到'√'请补为完整根号
;==========================================================
;清单1:支持基本运算的辅助程序: 包括双精度加法、减法、尾数逻辑/算术移位、交换数据、
;积商符号处理、尾数增1处理以及浮点数格式化等。它们也对函数计算提供支持等。
;清单2: 标号 FPCP 功能: 浮点数比较大小子程序
;清单3: 标号 FPSU/FPAD 功能: 浮点加、减法子程序
;清单4: 标号:FPMU 功能:浮点乘法子程序
;清单5: 标号:FPDI 功能:浮点除法子程序
;清单6: 标号:FPSQ 功能:浮点数模拟手算开平方子程序
;清单7 标号:FSQR 功能:浮点数牛顿迭代开平方子程序
;清单8: 基本运算子程序演示程序清单
;清单9: 标号:LD0 功能:装、存、取浮点数
;清单10:标号:FPLN1 功能:计算奇次多项式值(ln x、sin x、arcsin x 等)子程序
;清单11:标号: LNX,LGAX及LGX 功能:计算对数函数子程序
;清单12:标号: DXP 功能:计算...
;清单13:标号: COTX 功能:正弦函数及其衍生函数子程序
;清单14:标号: ASINX 功能:反正弦函数及其衍生函数子程序
;清单15:标号: DMST2 功能:函数子程序的演示程序
;清单16:标号:NP 功能:阶乘子程序
;清单17:标号: CONV1 功能:定点整数二翻十
;清单18:标号:DTOB1 功能:定点十进制数转为二进制浮点操作数
;清单19:标号: STRT 功能: 最小二乘法拟合直线程序
;清单20:标号: MUL16 功能:定点16位整数×16位整数→32位整数
;清单21
;标号: DTOB 功能: 将十进制浮点数转成二进制浮点数
;标号: BTOD 功能: 二进制浮点数转为十进制浮点数
;==========================================================
;==========================================================
;$include (REG52.INC)
ORG 0000H
JMP START
ORG 2000H
START:
MOV R0,#7FH
CLR A
START01:
MOV @R0,A
DJNZ R0,START01
MOV SP,#70H
AJMP DMST1
AJMP DMST2
AJMP $
;------------------------------------------------
;清单8: 基本运算子程序演示程序清单
;------------------------------------------------
DMST1: MOV SP,#70H ;基本运算子程序的演示程序
SETB RS0
CLR RS1 ;选取工作寄存器1(必须选用1)
;演示数据 50.265 ;可将数据直接放入工作寄存器,不必经过20H等去转
MOV R1,#00H ;十进制数阶符
MOV R2,#00H ;十进制数数符
MOV R3,#02H ;十进制数阶
MOV R4,#50H ;尾数,R4~R7为纯小数尾数,R4为高位字节
MOV R5,#26H
MOV R6,#50H
MOV R7,#00H ;取第1操作数
LCALL DTOB ;将十进制浮点数(浮点BCD码)转成二进制浮点数
;出口:二进制浮点数在R4,R5,R6,R7中
LCALL LD2 ;存入
MOV R1,27H
MOV R2,28H
MOV R3,29H
MOV R4,2AH
MOV R5,2BH
MOV R6,2CH
MOV R7,2DH ;取第2操作数
LCALL DTOB ;将十进制浮点数转成二进制浮点数
LCALL GET2 ;取第1操作数
LCALL FPAD ;调加、减、乘、除、对数函数、指数函数子程序之一
MOV R4,#7AH ;0.1的浮点数
MOV R5,#0A3H
MOV R6,#0D7H
MOV R7,#0AH
LCALL BTOD ;将二进制浮点数转换成十进制浮点数
SJMP $
;------------------------------------------------
;清单15: 标号:DMST2 功能:函数子程序的演示程序
;------------------------------------------------
DMST2: MOV SP,#70H
SETB RS0
MOV R1,27H
MOV R2,28H
MOV R3,29H
MOV R4,2AH
MOV R5,2BH
MOV R6,2CH
MOV R7,2DH ;取操作数
LCALL DTOB ;转成二进制浮点数
LCALL LNX ;调函数子程序(单操作数,包括开平方)
LCALL BTOD ;二进制浮点数转为十进制浮点数
SJMP $
;================================================
;================================================
; 清单1
; 清单1_1标号: ADD0 功能:双精度加法
;入口条件:被加数在[R6]、[R7]中;加数在[R2]、[R3]中
;出口信息: []中
;影响资源:
;------------------------------------------------
; ORG 2000H
ADD0: CLR C ;双精度加法子程序
ADC0: XCH A,R7 ;双精度带进位位加法子程序
ADDC A,R3
XCH A,R7
XCH A,R6
ADDC A,R2
XCH A,R6
RET
ADD1: CLR C ;双精度加法子程序
ADC1: XCH A,R7 ;双精度带进位位加法子程序
ADDC A,R5
XCH A,R7
XCH A,R6
ADDC A,R4
XCH A,R6
RET
ADD2: CLR C ;双精度加法子程序
ADC2: XCH A,R7 ;双精度带进位位加法子程序
RLC A
XCH A,R7
XCH A,R6
RLC A
XCH A,R6
RET
;------------------------------------------------
; 清单1_2 标号: SUB0 功能:双精度减法
;入口条件:被减数在[]、[]中;减数在[]、[]中
;出口信息: []中
;影响资源:
;------------------------------------------------
SUB0: CLR C ;双精度减法子程序
SBC0: XCH A,R7 ;双精度带进位位减法子程序
SUBB A,R3
XCH A,R7
XCH A,R6
SUBB A,R2
XCH A,R6
RET
SUB1: CLR C ;双精度减法子程序
SBC1: XCH A,R7 ;双精度带进位位减法子程序
SUBB A,R5
XCH A,R7
XCH A,R6
SUBB A,R2
XCH A,R6
RET
;------------------------------------------------
; 清单1_3 标号: EX 功能:两浮点数的尾数交换
;入口条件:
;出口信息: []中
;影响资源:
;------------------------------------------------
EX: XCH A,R0 ;两浮点数交换子程序
XCH A,R4
XCH A,R0
EXT: XCH A,R1 ;两浮点数的尾数交换子程序
XCH A,R5
XCH A,R1
EXX: XCH A,R2 ;双字节交换
XCH A,R6
XCH A,R2
XCH A,R3
XCH A,R7
XCH A,R3
RET
;------------------------------------------------
; 清单1_4 标号: SAV0 功能:第1操作数(浮点数)装入0CH~0FH中
;入口条件:
;出口信息: []中
;影响资源:
;------------------------------------------------
SAV0: MOV R4,08H ;第1操作数(浮点数)装入0CH~0FH中
SAVT: MOV R5,09H
MOV R6,0AH
MOV R7,0BH
RET
;------------------------------------------------
;清单1_5 标号: DP 功能:计算积(商)的阶码
;入口条件:
;出口信息: []中
;影响资源:
;------------------------------------------------
DP: MOV A,R5 ;取存积(商)数符,计算积(商)的阶码子程序
XRL A,R1
RLC A
MOV 7EH,C ;存积(商)数符
MOV A,R0
ADD A,R4 ;阶码相加(除数阶码已变为补码)
JNC DP1
ADD A,#80H ;有进位,和再加上80H,如有进位,为溢出
MOV R4,A
RET
DP1: SUBB A,#80H ;无进位,和减去80H,如有借位或差等于0,也为溢出
MOV R4,A
RET
;------------------------------------------------
; 清单1_6 标号: SHIF、LR0、SRA0、RR0、INC3 功能:尾数移位
;入口条件:
;出口信息: []中
;影响资源:
;------------------------------------------------
SHIF: CLR C ;尾数算术左移1位子程序
H0: XCH A,R7 ;尾数带进位左移1位
RLC A
XCH A,R7
XCH A,R6
RLC A
XCH A,R6
XCH A,R5
RLC A
XCH A,R5
RET
LR0: XCH A,R3 ;尾数带进位位左移1位子程序
RLC A
XCH A,R3
XCH A,R2
RLC A
XCH A,R2
XCH A,R1
RLC A
XCH A,R1
RET
SRA0: CLR C ;尾数逻辑右移1位子程序
SRA: XCH A,R5 ;尾数带进位位右移1位
SRA1: RRC A ;A R6 R7带进位位右移1位,结果在R5 R6 R7中
XCH A,R5
XCH A,R6
RRC A
XCH A,R6
XCH A,R7
RRC A
XCH A,R7
RET
RR0: XCH A,R1 ;尾数带进位位右移1位子程序
RRC A
XCH A,R1
XCH A,R2
RRC A
XCH A,R2
XCH A,R3
RRC A
XCH A,R3
RET
INC3: INC R7 ;尾数增1子程序
CJNE R7,#0,RET0
INC R6
CJNE R6,#0,RET0
INC R5
RET0: RET
;------------------------------------------------
;清单2: 标号FPCP: 功能:浮点数比较大小的子程序
;参与比较的两个数分别为x1的x2,x1相当于被减数,x2相当于减数
;(按双操作数入口条件存放).
;比较结量如下: ACC=0时,x1=x2;否则,Cy=1时x1>x2,Cy=0时x1<x2
;* 浮点数0划规到正数范围内参与比较
;------------------------------------------------
FPCP: MOV A,R1 ;被减数x1与减数x2比较大小子程序
XRL A,R5
JNB ACC.7,CP1 ;两数同号,转CP1
CP0: MOV A,R1
CLR C
SUBB A,R5 ;异号,比较尾数高位字节即可
RET
CP1: MOV A,R1
JNB ACC.7,CP2 ;正数与正数相比较,转CP2
ACALL CP2
JZ CP4 ;除非两数相等,不然转CP4
CPL C ;负数与负数比较对CY的影响与正数相比恰恰相反
RET
CP2: MOV A,R4 ;先比较两数的阶
CLR C
SUBB A,R0
JNZ CP4 ;不等,即可定下大小关系
CP3: MOV A,R5
SUBB A,R1 ;阶相等时,由尾数相比较定大小
JNZ CP4
MOV A,R6 ;依高位字节到低位字节的顺序比较
SUBB A,R2
JNZ CP4
MOV A,R7 ;只有阶码和尾数对应相等时,两数才相等
SUBB A,R3 ;比较结果ACC=0,两数相等,不然CY=1时x1>x2,
CP4: RET ;CY=0时,x1<x2
;------------------------------------------------
;清单3 标号:FPSU/FPAD 功能:浮点加、减法子程序
;浮点加法规则为:两数相加,首先对阶,尾数相加(减),结果调整。
;减法:将减数数符求反后视为加数,将被减数视为被加数,转为加法计算.
;* 入口: 被加数: 08H(R0),09H(R1),0AH(R2),0BH(R3)
;* 加数: 0CH(R4),0DH(R5),0EH(R6),0FH(R7)
;* 出口: 0CH(R4),0DH(R5),0EH(R6),0FH(R7)
;------------------------------------------------
FPSU: XRL 0DH,#80H ;浮点减法子程序,减数数符求反后为加数
FPAD: MOV A,R0 ;浮点加法子程序
JZ DON ;被加数等于0,加数为和
FPLAD: MOV A,R4
JZ SAV0 ;加数等于0,被加数为和
NX2: MOV A,R1
RLC A
MOV 7AH,C ;存被加数数符
MOV A,R5
RLC A
MOV 7BH,C ;存加数数符
ORL 09H,#80H
ORL 0DH,#80H ;恢复尾数最高位
CLR C
MOV A,R4
SUBB A,R0 ;加数阶减去被加数的阶
JNC NX3
CPL A
INC A
MOV R4,A ;阶差为负,取绝对值
ADD A,#0E7H
JC EXAD ;|阶差|≥24,取被加数为和
ACALL SRA0 ;右移加数尾数,对阶
DJNZ R4,$-2
MOV A,R0
MOV R4,A ;被加数的阶(大阶)为和的阶
JNC GOON
ACALL INC3 ;尾数欲截去部分四舍五入
SJMP GOON
NX3: MOV R0,A
JZ GOON ;阶差为0,不对阶
ADD A,#0E7H
JC COM ;阶差≥24,取加数为和
LOOP: CLR C
CALL RR0
DJNZ R0,LOOP ;右移被加数尾数,对阶
JNC GOON
INC R3
CJNE R3,#0,GOON
INC R2
CJNE R2,#0,GOON
INC R1 ;对尾数截去部分四舍五入
GOON: MOV A,2FH
ADD A,#4 ;判断两数符是否相同
JNB ACC.3,SAMS ;同号,转SAMS
CALL SUB0 ;异号,尾数相减,以加数作为被减数
MOV A,R5
SUBB A,R1
MOV R5,A
JNC NOM
CPL 7BH ;不够减,加数数符求反
CLR C
CLR A
SUBB A,R7
MOV R7,A
CLR A
SUBB A,R6
MOV R6,A
CLR A
SUBB A,R5
MOV R5,A ;差求补
NOM: MOV A,R5
ORL A,R6
ORL A,R7
JZ DON0 ;差为0,取阶码为0
NX5: MOV A,R5
JB ACC.7,COM
ACALL SHIF
DJNZ R4,NX5 ;左规检查
OV1: LJMP 0FFFFH ;阶码变为0,为溢出(可用LJMP指令引导处理溢出,下同)
SAMS: ACALL ADD0 ;同号,执行加法
MOV A,R5
ADDC A,R1
MOV R5,A
JNC COM
ACALL SRA ;有进位,右规1次
INC R4
MOV A,R4
JZ OV1
COM: JBC 7BH,DON
COMA: ANL 0DH,#7FH ;配置数符
DON: RET
EXAD: ACALL SAV0 ;取被加数为和
JNB 7AH,COMA ;置数符
RET
DON0: MOV R4,A ;取浮点数0的阶码
RET
;------------------------------------------------
;清单4 标号:FPMU 功能:浮点乘法子程序
;浮点乘法法则为: 两数相乘,阶码相加,尾数相乘,结果调整.
;入口:被乘数R0,R1,R2,R3 ;乘数R4,R5,R6,R7
;出口:积在 R4,R5,R6,R7
;------------------------------------------------
FPMU: MOV A,R0 ;浮点乘法子程序
JZ M0
MOV A,R4
JNZ M1
M0: AJMP G0 ;乘数中有为0者,积为0
M1: ACALL DP ;积符,积阶码处理
JZ OV2
JC OV2 ;积阶码处理结果,为0或CY=1为溢出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -