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;