home *** CD-ROM | disk | FTP | other *** search
- 03/22/86 [ using V1.11]
-
- Inaccuracies in the Ln and Exp functions
- and some ways around them.
-
- While writing some financial calculation routines, I needed a power function
- to raise a number to any power. Since Pascal does not have a built-in power
- function, I wrote a very simple one:
-
- --------------------------------
-
- FUNTION Power(base, exponent : Real ) : Real ;
-
- {* This function merely raises the base to a power specified by the
- * exponent using the relation
- * y
- * Ln X = y * Ln X
- *
- * y y * Ln X
- * X = e }
-
-
- BEGIN
- Power := Exp( exponent * Ln(base) ) ;
- END;
-
- ---------------------------------
-
-
- However, by comparing the answers I was getting to standard financial tables, I
- noticed that the answers I was getting were only accurate to 5 or 6 digits.
-
- I then wrote a simple routine to display ln(x) and exp(x) for various
- values of x and found that the routines were accurate for values of x near one,
- but became increasingly less accurate for larger values.
-
- I then wrote the following two functions which can be used in place of
- the built in exp and ln functions. Neither is extremely elegant or fast for
- all arguments, but they give the right answers.
-
- -----------------------------------------------------
-
- FUNCTION Exp_new ( exponent : Real ) : Real ;
-
- {* The exp and ln functions furnished with Personal Pascal are not accurate
- * for large ranges of arguments. This function calculates exp(x) using a
- * Taylor Series. If the exponent is less than zero, then the absolute value
- * of the exponent is used in the calculation and the result inverted. }
-
- CONST Error = 5.0E-12 ;
-
- VAR Total, Term, Dummy : Real ;
- Count : Integer ;
-
- Begin
-
-
- IF (exponent < 0) THEN
- Dummy := -1 * exponent
- Else Dummy := exponent ;
-
- Total := 0 ;
- Count := 0 ;
- Term := 1 ;
-
- Repeat
- Count := Count + 1 ;
- Total := Total + Term ;
- Term := (Term * Dummy) / Count ;
- Until ( Abs(Term) < Total * Error ) ;
-
- IF ( exponent >= 0 ) THEN Exp_new := Total
- Else Exp_new := 1/Total ;
-
- End ;
-
- ------------------------------------------------------------
-
-
- FUNCTION Ln_new ( arg : Real ) : Real ;
-
- {* The exp and ln functions furnished with Personal Pascal are not accurate
- * for large ranges of arguments. This function calculates ln(x) using
- * Newton's iterative method to solve the equation:
- * x
- * e - arg = 0
- *
- * Notice that this function has to call exp_new. }
-
- CONST Error = 5.0E-12 ;
-
- VAR X1, X2 : Real ;
-
- BEGIN
-
- { * The first IF-THEN takes care of the special case when arg=1 }
- IF (arg = 1) THEN
- Ln_new := 0
- ELSE
- BEGIN
-
- { * The next IF-THEN chooses a more favorable starting point for iterations for
- * large values of arg. [ You could improve on this section if you want more
- * speed for large values of arg.]
-
- IF (arg > 10) THEN
- X2 := arg/10
- ELSE
- X2 := arg ;
-
- { * Now solve the equation. }
- Repeat
- X1 := X2 ;
- X2 := X1 - 1 + arg * Exp_new( -1 * X1 ) ;
- Until ( ABS((X2-X1)/X1) <= Error) ;
- Ln_new := X2 ;
- END ;
-
-
- END ;
-
- ------------------------------------------------
- MIKE GUIDRY
- CIS: 71046,144
- I also hang out on the Seattle and New Jersey ST BBS's.
-