📄 floexp.asm
字号:
;********************FLOEXP********************
;本程序求标准浮点数指数函数EXP(x)。
;入口参数:X在ARGBH1:ARGBL1:EXP1中。
;出口参数:EXP(X)在ARGBH1:ARGBL1:EXP1中。
;占用资源:W,STATUS,020H~02CH,3重堆栈。
;说明: 1.用户需自行指定 AARGB4,AARGB5,AARGB7,DEXP,DARGB1,DARGB2,DARGB3
; 2.加载本文件的同时也加载了另外2个文件"FLOTDS.ASM","FLOOR.ASM"
; 故用户在使用这2个子程序时可直接调用,不必重新加载.
IFNDEF FLOEXP1
#DEFINE FLOEXP1
INCLUDE "RND3224.ASM"
INCLUDE "FXM2416U.ASM"
INCLUDE "FLOFLOOR.ASM"
INCLUDE "FLOTDS.ASM"
INCLUDE "MUAD32.ASM"
FLOEXP MOVLW 0x66 ;检测是否 |x| < 2**(-24)/2
SUBWF EXP,W
MOVWF TEMP1
BTFSC TEMP1,MSB
GOTO EXP24ONE ;返回 e**x = 1
BTFSC AARGB0,MSB ;检测符号位
GOTO TNEXP24
TPEXP24
MOVF AEXP,W ;是正数,检查定义域
SUBLW MAXLOG24EXP
BTFSS STATUS,C
GOTO DOMERR24
BTFSS STATUS,Z
GOTO EXP24ARGOK
MOVF AARGB0,W
SUBLW MAXLOG24B0
BTFSS STATUS,C
GOTO DOMERR24
BTFSS STATUS,Z
GOTO EXP24ARGOK
MOVF AARGB1,W
SUBLW MAXLOG24B1
BTFSS STATUS,C
GOTO DOMERR24
GOTO EXP24ARGOK
TNEXP24
MOVF AEXP,W ;负数定义域检查
SUBLW MINLOG24EXP
BTFSS STATUS,C
GOTO DOMERR24
BTFSS STATUS,Z
GOTO EXP24ARGOK
MOVF AARGB0,W
SUBLW MINLOG24B0
BTFSS STATUS,C
GOTO DOMERR24
BTFSS STATUS,Z
GOTO EXP24ARGOK
MOVF AARGB1,W
SUBLW MINLOG24B1
BTFSS STATUS,C
GOTO DOMERR24
EXP24ARGOK
MOVF FPFLAGS,W
MOVWF DARGB3 ;保存RND位
BCF FPFLAGS,RND ;屏蔽圆整标志
CALL RREXP24 ;压缩自变量定义域
MOVLW 0x7E
SUBWF AEXP,W
BTFSS STATUS,Z
GOTO EXP24L
EXP24H BTFSS AARGB0,MSB-1
GOTO EXP24HL
POL EXP24HH,3,0 ; [.75,1]
GOTO EXP24OK
EXP24HL POL EXP24HL,3,0 ; [.5,.75]
GOTO EXP24OK
EXP24L MOVLW 0x7D
SUBWF AEXP,W
BTFSS STATUS,Z
GOTO EXP24LL
POL EXP24LH,3,0 ; [.25,.5]
GOTO EXP24OK
EXP24LL POL EXP24LL,3,0 ; [0,.25]
EXP24OK
MOVF EARGB3,W
ADDWF AEXP,F
BTFSS DARGB3,RND
RETLW 0x00
BSF FPFLAGS,RND ;恢复RND位
GOTO RND3224
EXP24ONE MOVLW .127 ;返回 e**x = 1.0
MOVWF AEXP
CLRF AARGB0
CLRF AARGB1
CLRF AARGB2
RETLW 0x00
;**********************************************************************************************
; Range reduction routine for the exponential function
; x/log(2) = z + n
RREXP24
MOVF AARGB0,W ;保存符号位
MOVWF EARGB3
BSF AARGB0,MSB ;现露最高位隐含的1
MOVF AARGB0,W
MOVWF BARGB0
MOVF AARGB1,W
MOVWF BARGB1
MOVLW 0xB8 ; 1/ln(2) = 1.44269504089
MOVWF AARGB0
MOVLW 0xAA
MOVWF AARGB1
MOVLW 0x3B
MOVWF AARGB2
CALL FXM2416U ; x * (1/ln2)
INCF AEXP,F
BTFSC AARGB0,MSB
GOTO RREXP24YOK
RLF AARGB3,F
RLF AARGB2,F
RLF AARGB1,F
RLF AARGB0,F
DECF AEXP,F
RREXP24YOK BTFSS EARGB3,MSB
BCF AARGB0,MSB
CALL RND4032
MOVF AEXP,W
MOVWF BEXP ;将N+Z保存在BARG中
MOVF AARGB0,W
MOVWF BARGB0
MOVF AARGB1,W
MOVWF BARGB1
MOVF AARGB2,W
MOVWF BARGB2
CALL FLOFLOOR
MOVF AEXP,W
MOVWF DEXP ;将 float(n) 保存在 DARG
MOVF AARGB0,W
MOVWF DARGB0
MOVF AARGB1,W
MOVWF DARGB1
CALL FLOTDS ; n = [ x * (1/ln2) ]
MOVF AARGB1,W
MOVWF EARGB3 ;n保存在EARG中
MOVF DEXP,W
MOVWF AEXP
MOVF DARGB0,W
MOVWF AARGB0
MOVF DARGB1,W
MOVWF AARGB1
CLRF AARGB2
MOVLW 0x80 ;符号取反
XORWF AARGB0,F
CALL FPA32
CALL RND4032
MOVF AEXP,W
MOVWF DEXP ;z 保存在 DARG
MOVF AARGB0,W
MOVWF DARGB0
MOVF AARGB1,W
MOVWF DARGB1
MOVF AARGB2,W
MOVWF DARGB2
RETLW 0x00
;***********40位浮点数向32为浮点数圆整***********************
RND4032
BTFSS AARGB3,MSB ; is NSB < 0x80?
RETLW 0x00
BSF STATUS,C ; set carry for rounding
MOVLW 0x7F
ANDWF AARGB3,W
BTFSC STATUS,Z
RRF AARGB2,W ; select even if NSB = 0x80
MOVF AARGB0,W
MOVWF SIGN ; save sign
BSF AARGB0,MSB ; make MSB explicit
BCF STATUS,Z
BTFSC STATUS,C ; round
INCF AARGB2,F
BTFSC STATUS,Z
INCF AARGB1,F
BTFSC STATUS,Z
INCF AARGB0,F
BTFSS STATUS,Z ; has rounding caused carryout?
GOTO RND4032OK
RRF AARGB0,F ; if so, right shift
RRF AARGB1,F
RRF AARGB2,F
INCF EXP,F ; test for floating point overflow
BTFSC STATUS,Z
GOTO SETFOV32
RND4032OK
BTFSS SIGN,MSB
BCF AARGB0,MSB ; clear sign bit if positive
RETLW 0x00
;************************************************************************************************
; Maximum argument to EXP24
MAXLOG24EXP equ 0x85 ; 88.7228391117 = log(2**128)
MAXLOG24B0 equ 0x31
MAXLOG24B1 equ 0x72
; Minimum argument to EXP24
MINLOG24EXP equ 0x85 ; -87.3365447506 = log(2**-126)
MINLOG24B0 equ 0xAE
MINLOG24B1 equ 0xAC
;----------------------------------------------------------------------------------------------
; third degree minimax polynomial coefficients for 2**(x) on [.75,1]
EXP24HH0 EQU 0x7E ; EXP24HH0 = .99103284632
EXP24HH00 EQU 0x7D
EXP24HH01 EQU 0xB4
EXP24HH02 EQU 0x54
EXP24HH1 EQU 0x7E ; EXP24HH1 = .73346850266
EXP24HH10 EQU 0x3B
EXP24HH11 EQU 0xC4
EXP24HH12 EQU 0x97
EXP24HH2 EQU 0x7C ; EXP24HH2 = .17374128273
EXP24HH20 EQU 0x31
EXP24HH21 EQU 0xE9
EXP24HH22 EQU 0x3C
EXP24HH3 EQU 0x7B ; EXP24HH3 = .10175678143
EXP24HH30 EQU 0x50
EXP24HH31 EQU 0x65
EXP24HH32 EQU 0xDC
; third degree minimax polynomial coefficients for 2**(x) on [.5,.75]
EXP24HL0 EQU 0x7E ; EXP24HL0 = .99801686089
EXP24HL00 EQU 0x7F
EXP24HL01 EQU 0x7E
EXP24HL02 EQU 0x08
EXP24HL1 EQU 0x7E ; EXP24HL1 = .70586404164
EXP24HL10 EQU 0x34
EXP24HL11 EQU 0xB3
EXP24HL12 EQU 0x81
EXP24HL2 EQU 0x7C ; EXP24HL2 = .21027360637
EXP24HL20 EQU 0x57
EXP24HL21 EQU 0x51
EXP24HL22 EQU 0xF7
EXP24HL3 EQU 0x7B ; EXP24HL3 = .85566912730E-1
EXP24HL30 EQU 0x2F
EXP24HL31 EQU 0x3D
EXP24HL32 EQU 0xB5
; third degree minimax polynomial coefficients for 2**(x) on [.25,.5]
EXP24LH0 EQU 0x7E ; EXP24LH0 = .99979384559
EXP24LH00 EQU 0x7F
EXP24LH01 EQU 0xF2
EXP24LH02 EQU 0x7D
EXP24LH1 EQU 0x7E ; EXP24LH1 = .69545887384
EXP24LH10 EQU 0x32
EXP24LH11 EQU 0x09
EXP24LH12 EQU 0x98
EXP24LH2 EQU 0x7C ; EXP24LH2 = .23078300446
EXP24LH20 EQU 0x6C
EXP24LH21 EQU 0x52
EXP24LH22 EQU 0x61
EXP24LH3 EQU 0x7B ; EXP24LH3 = .71952910179E-1
EXP24LH30 EQU 0x13
EXP24LH31 EQU 0x5C
EXP24LH32 EQU 0x0C
; third degree minimax polynomial coefficients for 2**(x) on [0,.25]
EXP24LL0 EQU 0x7E ; EXP24LL0 = .99999970657
EXP24LL00 EQU 0x7F
EXP24LL01 EQU 0xFF
EXP24LL02 EQU 0xFB
EXP24LL1 EQU 0x7E ; EXP24LL1 = .69318585159
EXP24LL10 EQU 0x31
EXP24LL11 EQU 0x74
EXP24LL12 EQU 0xA1
EXP24LL2 EQU 0x7C ; EXP24LL2 = .23944330933
EXP24LL20 EQU 0x75
EXP24LL21 EQU 0x30
EXP24LL22 EQU 0xA0
EXP24LL3 EQU 0x7A ; EXP24LL3 = .60504944237E-1
EXP24LL30 EQU 0x77
EXP24LL31 EQU 0xD4
EXP24LL32 EQU 0x08
ENDIF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -