home *** CD-ROM | disk | FTP | other *** search
- program TPWRN;
- {TPWRN.PAS #1.02 85-06-20 TEST POWERN.PLB CALCULATION OF POWERS
-
- V01 L02 update on 85-06-20 by DEH to exhibit precision-maintenance
- difficulties with (1/7)**(-i) and exp(i*ln(7)) variations.
- L01 update on 85-06-09 by DEH to compute error deviation of
- exp(ln) competitor a bit more carefully.
- L00 created on 85-06-05 by Dennis E. Hamilton, just for
- demonstration of generally-correct overall operation of
- the algorithm in Turbo Pascal module POWERN.PLB.}
-
- {$I POWERN.PLB } {Vintage 1.00}
-
-
- var i: integer {counter of trial exponents};
- p7: real {intermediate power of 7 to be checked};
- ln7: real {logarithm of 7 used in comparison with exp(ln) method};
- rv7: real {value of 1/7 used in showing precision loss};
-
- out: text {file variable used for direction of output as needed};
-
- BEGIN {Testing the basic features of POWERN.PLB}
-
- assign(out, 'CON:');
- {V01 L02 change to a disk file when you want to capture the report in
- a file for comparison, uploading, etc.}
- rewrite(out);
-
- writeln(out, 'TPWRN> #1.02 85-06-20 TEST OF POWERN FUNCTION RESULTS');
- writeln(out);
-
- writeln(out, ' I (-1)**I p = 7**I (1/7)**-I - p',
- ' exp(I*ln(7)) - p');
- writeln(out);
-
- ln7 := ln(7.0);
- rv7 := 1.0/7.0;
- for i := 0 to 17
- do begin
- write(out, ' ', i:2);
- write(out, PowerN(-1,i) :11:0);
- p7 := PowerN(7.0,i);
- write(out, p7 :16:0);
- {It is important to use a number that is prime to the base. Although
- 5 is easier to follow, it isn't so hot when Turbo-BCD is used.}
- write(out, PowerN(rv7, -i) - p7 :20:13);
- {V01 L02 use the inexact reciprocal to show how errors magnify}
- writeln(out, exp(i*ln7) - p7 :21:13);
- {V01 L02 show deviation of exp(i*ln(7)) on the same basis}
- end;
-
- close(out);
- END.
- {
- TPWRN> #1.02 85-06-20 TEST OF POWERN FUNCTION RESULTS
-
- I (-1)**I p = 7**I (1/7)**-I - p exp(I*ln(7)) - p
-
- 0 1 1 0.0000000000000 0.0000000000000
- 1 -1 7 0.0000000000000 -0.0000000000146
- 2 1 49 0.0000000000582 -0.0000000003492
- 3 -1 343 0.0000000009313 -0.0000000032596
- 4 1 2401 0.0000000074506 -0.0000000298023
- 5 -1 16807 0.0000000596046 -0.0000003874302
- 6 1 117649 0.0000008344650 -0.0000026226044
- 7 -1 823543 0.0000057220459 -0.0000362396240
- 8 1 5764801 0.0000457763672 -0.0001296997070
- 9 -1 40353607 0.0003662109375 -0.0009155273438
- 10 1 282475249 0.0029296875000 -0.0126953125000
- 11 -1 1977326743 0.0234375000000 -0.0859375000000
- 12 1 13841287201 0.1875000000000 -0.6250000000000
- 13 -1 96889010407 1.3750000000000 -4.2500000000000
- 14 1 678223072850 11.0000000000000 -58.0000000000000
- 15 -1 4747561509900 80.0000000000000 -400.0000000000000
- 16 1 33232930570000 640.0000000000000 -1472.0000000000000
- 17 -1 232630513990000 4864.0000000000000 -20224.0000000000000
-
- These results were obtained by assign(out, 'TPWRN.PRN') and compiling with
- POWERN.PLB #1.03. CP/M-80 Turbo Pascal version 3.00A was used.
-
- Similar results should be obtained using MS-DOS, CP/M-86 and IBM PC
- versions of Turbo Pascal. Turbo-8087 should obtain better results in all
- columns because of the greater precision maintained internally. Turbo-BCD
- should also show improvements, with decreased speed, after the last column
- is either dropped or library procedures for BCD ln() and exp() are obtained.
- (For Turbo-BCD and Turbo-8087 both, it is instructive to increase the number
- of decimal positions in the last two columns in order to see what error there
- is, however much smaller it turns out to be.)
-
- Note that, in this test, the 7**I powers are produced quite rapidly and
- exactly with I<14. Thereafter, the 39-bit effective precision is inadequate
- for maintenance of an exact result.
-
- On the other hand, the use of (1/7)**-I, although MATHEMATICALLY the
- same as 7**I, deteriorates much more quickly. That is because 1/7 cannot
- be carried exactly, and this error is quickly magnified in the taking of
- powers. By I=14, the error has grown to 10, just as minimum error shows
- in the lowest digit of 7**I. (Handling of the 1/7-th column may also be
- affected by rounding characteristics of this compiler's floating-point
- implementation. We are less concerned, here, with placing blame than with
- showing the problem to be inevitable unless other steps are taken.)
-
- The final column shows how much more quickly the calculus textbook approach,
- using exp(I*ln(7)), breaks down. Since this method is NOTICEABLY slower as
- well, there is nothing to commend it.
-
- In making use of these results, keep in mind that the PowerN vintage 1.xx
- Algorithms are the best available in terms of direct solution at minimum cost.
- Nevertheless, working in the same precision as the input data dooms us to some
- sort of error. This may be tolerable, but it is well to know of its presence.
-
- If taking powers still seems the best approach in the problem at hand, but
- maximum precision must be obtained, more complex techniques using expanded-
- precision internal values must be substituted in the implementation of PowerN.
- The techniques are not directly realizable in Pascal, however. It is necessary
- to "get under the hood" in order to expand the precision of calculation. That
- is what makes finding an alternative problem approach all the more attractive.
- (For further background on these techniques, consult the bibliographical notes
- appended to the POWERN.PLB module.)
-
- -- Dennis E. Hamilton
- 1985 June 20 }
-
-
- (* end of TPWRN.PAS *)