size : 2667 uploaded_on : Tue Oct 27 00:00:00 1998 modified_on : Wed Dec 8 14:03:23 1999 title : Raising a number to a power org_filename : value2power.txt author : Paul Cunningham authoremail : pjcunningham@cix.compulink.co.uk description : Robust implementation, taking into account every possible input. keywords : tested : not tested yet submitted_by : Unofficial Delphi Developers FAQ submitted_by_email : uddf@gnomehome.demon.nl uploaded_by : nobody modified_by : nobody owner : nobody lang : pas file-type : text/plain category : pascal-alg-maths __END_OF_HEADER__ Raising a number to a power Paul Cunningham (pjcunningham@cix.compulink.co.uk) Question[ This may sound trivial, but how do you raise a value to a power? eg). 2^12 = 4095 ] The question is not that trivial. The trouble is that the power function is not that simple. Several distinct situations need to be considered for the function Power(X, N) i.e X^N. 1.X don't care, N = 0 2.X = 1, N don't care 3.X = 0 and N > 0 4.X = 0 and N < 0 5.X > 0 6.X < 0 and N is an odd integer 7.X < 0 and N is an even integer 8.X < 0 and N not an integer Consider the following robust (though not necessarily the most efficient!) power function. interface type EPowerException = class(Exception) end; implementation function Power(X, N : real) : extended; var t : longint; r : real; isInteger : boolean; begin if N = 0 then begin result := 1.0; exit; end; if X = 1.0 then begin result := 1.0; exit; end; if X = 0.0 then begin if N > 0.0 then begin result := 0.0; exit; end else raise EPowerException.Create('Infinite Result'); end; if (X > 0) then try result := exp(N * ln(X)); exit; except raise EPowerException.Create('Overflow/Underflow Result'); end; { X is negative but we still may compute the result if n is an integer} { try and get integer portion of n into a longint, it will be quicker to } { compute odd n} try t := trunc(n); if (n - t) = 0 then isInteger := true else isInteger := False; except {Bit superfluous as result will probably underflow/overflow anyway} r := int(n); if (n - r) = 0 then begin isInteger := true; if frac(r/2) = 0.5 then t := 1 else t := 2; end else isInteger := False; end; if isInteger then begin {n is an integer} if odd(t) then {n is odd} try result := -exp(N * ln(-X)); exit; except raise EPowerException.Create('Overflow/Underflow Result'); end else {n is even} try result := exp(N * ln(-X)); exit; except raise EPowerException.Create('Overflow/Underflow Result'); end; end else raise EPowerException.Create('Complex Result'); end;