|
|

Watch, Follow, &
Connect with Us

Developer Tools Community.

# 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.0E-16 1.0 1.0E-16 1.0E-16 0.0 1.0E-16 2.0 1.0E-16 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 = 1e-15;

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 1e-16 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 units 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.

Server Response from: ETNASC03