08-12-2003, 09:23 AM
If anyone else is interested, this is my codeIt's fairly simple, but as usual took me way too long (I specialize in typos). I can't understand how so many of you were able to write decent games in an hour.
Oracle,
I have made a minor change in the convergence test (LOOP) lines. You may have noticed that I was calculating a value I already knew.
Code:
DECLARE FUNCTION eM# (BYVAL x#)
DECLARE FUNCTION eT# (BYVAL x#)
DECLARE FUNCTION lnT# (BYVAL x#)
DECLARE FUNCTION AToTheX# (BYVAL a#, BYVAL x#)
INPUT "Enter a,x: ", a, x
PRINT a; " ^"; x; "="; AToTheX(a, x)
DEFDBL A-Z
FUNCTION AToTheX (BYVAL a, BYVAL x)
AToTheX = eT(x * lnT(a))
END FUNCTION
FUNCTION eM (BYVAL x)
' MacLaurin Series for e^x
' Not used
' Is slow to converge for all but small numbers.
' Very slow for large numbers.
' Does not agree with EXP(X) for x<-4. For example
' eM (-9.9) only returns single precision accuracy
' (assuming EXP is correct)
n = 0 '\ n = 0
e2 = 1 '/ term
DO
e1 = e2 ' Previous value for series
n = n + 1 '\
Term = 1 ' | nth term
FOR j = 1 TO n ' |
Term = Term * x / j ' | x^n / n!
NEXT '/
e2 = e2 + Term ' New value for series
LOOP WHILE ABS(Term) > e2 / 1D+16 ' Convergence check
' PRINT "n ="; n; ' test code (delete)
eM = e2 ' Function assignment
END FUNCTION
FUNCTION eT (BYVAL x)
' Taylor Series for e^x
' This converges faster than the MacLauren series,
' but has a large overhead to overcome. For large
' numbers it is definitely faster.
' It agrees well with EXP(x) (The last digit is sometimes off)
C = INT(x) + (x = 1) ' c=0 when x=1. This reduces the Taylor
' Series to the MacLauren series when
' x=1. You could gain some performance
' by extending this to small values of
' x. For example
' IF ABS(x - 1) < 4 THEN c = 0
dx = x - C
e0 = 1 '\
IF x > 1 THEN ' | Determine a value close to
e1 = eT(1#) ' | the desired value using an
FOR j = 1 TO C ' | integer exponent
e0 = e0 * e1 ' | (note e1 is used here for e^1,
NEXT ' | but is used differently below).
ELSEIF x < 0 THEN ' |
e1 = eT(1#) ' |
FOR j = 1 TO -C ' |
e0 = e0 / e1 ' |
NEXT ' |
END IF '/
n = 0 '\ first term
e2 = e0 '/ e^c
DO
e1 = e2 ' previous value
n = n + 1
Term = e0 '\
FOR j = 1 TO n ' | nth term
Term = Term * dx ' | e^c * (x - c)^n / n!
NEXT '/
e2 = e2 + Term ' New value of series
LOOP WHILE ABS(Term) > e2 / 1D+16 ' convergence check
' PRINT "n ="; n; ' for test purposes only (delete)
eT = e2 ' Function assignment
END FUNCTION
FUNCTION lnT (BYVAL x)
' Taylor series for ln x
' (only valid for x > 0)
' estimate ln
x$ = STR$(x) '\
DE = INSTR(x$, "D") + INSTR(x$, "E") ' |
IF DE > 0 THEN ' |
Pwr10 = VAL(RIGHT$(x$, 2)) ' |
Mantissa = VAL(LEFT$(x$, DE)) ' | Convert to scientific
ELSE ' | notation so that I can
Pwr10 = INSTR(x$, ".") - 3 ' | use LOG to estimate the
IF Pwr10 = -1 THEN ' | the ln. If you round
ChrPos = 3 ' | the mantissa off to
WHILE MID$(x$, ChrPos, 1) = "0" ' | double precision you
CurPos = ChrPos + 1 ' | will be able to use
WEND ' | LOG to estimate
Pwr10 = 2 - ChrPos ' |
END IF ' |
Mantissa = x / 10 ^ Pwr10 ' |
END IF '/
Mantissa = INT(1000 * Mantissa + .5) / 1000 ' rounding to approximate
' what you will be doing
n = 0
ln2 = LOG(Mantissa) + Pwr10 * LOG(10) ' n=0 term (Estimated Ln)
C = eT(ln2) ' Use ln2 to determine C
dx = x - C
DO
ln1 = ln2 ' Previous value for series
n = n + 1
Term = -1 / n '\
FOR j = 1 TO n ' | nth term
Term = -Term * dx / C ' | (-1)^n*(x - c)^n/(-n*c^n)
NEXT '/
ln2 = ln2 + Term ' New value for series
LOOP WHILE ABS(Term) > ABS(ln2 / 1D+17) ' Convergence test
' PRINT n ' test code (delete)
lnT = ln2 ' Function assignment
END FUNCTION
Oracle,
I have made a minor change in the convergence test (LOOP) lines. You may have noticed that I was calculating a value I already knew.
hrist Jesus came into the world to save sinners, of whom I am first.(I Timothy 1:15)
For God so loved the world, that He gave His only begotten Son,
that whoever believes in Him should not perish, but have eternal life.(John 3:16)
For God so loved the world, that He gave His only begotten Son,
that whoever believes in Him should not perish, but have eternal life.(John 3:16)