Re: Do you know these 2 functions ? Message #8 Posted by PGILLET on 21 Dec 2011, 6:14 a.m., in response to message #5 by Oliver Unter Ecker
Quote:
These are really sweet. Thank you for sharing!
Did you develop them yourself?
I think I'm going to use them in a calculator I know...
One should note that int() needs to do more than truncate to an int. It needs to round to internal precision as well, or you get something like 2.5111111111 for y2(2.3) (using IEEE754 doubles).
Hello,
Yes, I discovered these 2 formulas years ago.
Are they known elsewhere ?
You're right about rounding to internal precision:
That's what I do now in my implementation of the dd>dms formula on the TI86 as a builtin function
The TI86 computes 14 digits and displays 12 => Rounding is done to 12 digits before and after the formula:
(It's good old Z80 programming)
ld hl,_OP1 ; hl = OP1 address (Floating point register number 1)
ld a,(hl) ; Get OP1 flag byte
ld (mem1),a ; save OP1 flag byte
and $7F ; Clear sign bit => positive
ld (hl),a ; OP1=abs(x)
call _RNDGUARD ; OP1=OP1 rounded to 12 digits (abs(x) rounded, I call it x')
call _op1toop4 ; OP4=OP1 (x')
ld hl,n90
call _mov10toop2 ; OP2=90
call _FPMULT ; OP1=OP1*OP2 (90*x')
call _op1toop5 ; OP5=OP1 (90*x')
call _op4toop1 ; OP1=OP4 (x')
call _INTGR ; OP1=int(OP1) (int(x'))
ld hl,n100
call _mov10toop2 ; OP2=100
call _FPMULT ; OP1=OP1*OP2 (100*int(x'))
call _op5toop2 ; OP2=OP5 (90*x')
call _FPADD ; OP1=OP1+OP2 (90*x'+100*int(x'))
call _op1toop5 ; oP5=OP1 (90*x'+100*int(x'))
call _op4toop1 ; OP1=OP4 (x')
ld hl,n60
call _mov10toop2 ; OP2=60
call _FPMULT ; OP1=OP1*OP2 (60*x')
call _INTGR ; OP1=int(OP1) (int(60*x'))
call _op5toop2 ; OP2=OP5 (90*x'+100*int(x'))
call _FPADD ; OP1=OP1+OP2 (90*x'+100*int(x')+int(60*x'))
ld hl,n250
call _mov10toop2 ; OP2=250
call _FPDIV ; OP1=OP1/OP2 ((90*x'+100*int(x')+int
(60*x'))/250)
call _RNDGUARD ; OP1=OP1 rounded to 12 digits
ld a,(mem1)
and $80 ; Keep sign bit only
ld hl,_OP1
or (hl)
ld (hl),a ; Restore sign bit
ret
