[All]
Delphi and the Power Function
By: Charles Calvert
Abstract: This article talks about Delphi and the Power function
Overview
This article provides an overview of raising a number to
some arbitrary power in a Delphi program.
Discussion
Some computer languages have a power operator that raises a
value to a power. In Fortran for
example the operator is ** as in 2.0**3.0 which returns 8.0. Ada also uses the ** notation and Basic uses
the ^ symbol. For some reason, Pascal
and C do not include this operator.
That is particularly odd because Algol60, which was the ancestor of
both, did have a power operator, (^).
For years, the solution in Pascal has been to use a function usually
given as
function Power(x, y :extended) : extended;
begin
result := exp(y*ln(x));
end;
The problem with that easy answer is that this function will
fail (raise an exception) for a negative base value.
Base

Exponent

Simple

Delphi

Jack

Excel

1.0E16

1.0

1.0E16

1.0E16

0.0

1.0E16

2.0

1.0E16

1.0

1.0

1.0

1.0

2.0

2.0

4.0

4.0

4.0

4.0

3.0

3.0

27.0

27.0

27.0

27.0

3.0

2.0

Exception

9.0

9.0

9.0

3.0

3.0

Exception

27.0

27.0

27.0

3.0

3.0

0.0370370...

0.0370370...

0.0370370...

0.0370370...

3.0

3.0

Exception

0.0370370...

0.0370370...

0.0370370...

pi

pi

36.462159

36.462159

36.462159

36.462159

The function can be made to work if all the special cases
are considered.
{** A power function from Jack Lyle. Said to be more powerful than the
Pow function that comes with Delphi. }
function Power2(Base, Exponent : Double) : Double;
{ raises the base to the exponent }
CONST
cTiny = 1e15;
VAR
Power : Double; { Value before sign correction }
BEGIN
Power := 0;
{ Deal with the near zero special cases }
IF (Abs(Base) < cTiny) THEN BEGIN
Base := 0.0;
END; { IF }
IF (Abs(Exponent) < cTiny) THEN BEGIN
Exponent := 0.0;
END; { IF }
{ Deal with the exactly zero cases }
IF (Base = 0.0) THEN BEGIN
Power := 0.0;
END; { IF }
IF (Exponent = 0.0) THEN BEGIN
Power := 1.0;
END; { IF }
{ Cover everything else }
IF ((Base < 0) AND (Exponent < 0)) THEN
Power := 1/Exp(Exponent*Ln(Base))
ELSE IF ((Base < 0) AND (Exponent >= 0)) THEN
Power := Exp(Exponent*Ln(Base))
ELSE IF ((Base > 0) AND (Exponent < 0)) THEN
Power := 1/Exp(Exponent*Ln(Base))
ELSE IF ((Base > 0) AND (Exponent >= 0)) THEN
Power := Exp(Exponent*Ln(Base));
{ Correct the sign }
IF ((Base < 0) AND (Frac(Exponent/2.0) <> 0.0)) THEN
Result := Power
ELSE
Result := Power;
END; { FUNCTION Pow }
This function, labeled Jack in the table above, returns the
correct values if you will allow that 1e16 is the same as 0.0.
Delphi 4 added a standard math unit to the Borland Pascal
distribution. That unit includes a
power function and an IntPower function.
For some reason, they are not overloaded. The Delphi power function also checks the special cases (in much
less verbose code than mine) and returns the correct answer.
So, for Delphi versions 4 and later use the math units
Power function. For older versions of
Delphi or Turbo Pascal use the Pow function given above. Do not use the simple Power function if you
expect to ever see a negative base as input.
Summary
In Delphi 4 and later, use the Power function from the math
unit. In earlier versions, use the Pow
function given below.

Connect with Us