No. of Recommendations: 0

rmhj,

* I could also imagine a compiler complaining about it, and refusing to answer: exponentiation is often done by means of logarithms, and could be evaluated:*

e(ln(e(ln(-4)*2))*0.75)

and ln(-4) would yield a domain error. Most, however, are smart enough to recognize squaring as a special case. I don't know if any would also realize that it could be re-cast legitimately as:

(-4)^(6/4) =

r = -4

r = r * r;

r = r * r * r;

r = sqrt(sqrt(tmp)) = 8

In an expression, it's likely that some machines would evaluate this or similar reduction considerably faster than most others.

Most compilers do distinguish between the case in which the exponent is of an INTEGER (C int, long, or char, either signed or unsigned) type and the case in which the exponent is of a REAL (C float, double, or long double) type. Note that (-|x|)^n is mathematically legal if n is an integer.

Algorithmically, the logarithmic approach that you describe (a^b -> exp(log(a)*b) applies only if b is of a REAL type. If the exponent is an integer, the following function is more efficient. Note that this algorithm handles negative arguments correctly.

** C/C++ Version **

float expon(float x, int n)

{

float y, z;

int k;

if (n < 0.0) y = 1.0 / x;

else y = x;

k = abs(n);

whioe (k > 0)

{

if (k % 2 > 0) z *= y;

y *= y;

k /= 2;

}

return z;

}

** Fortran Version **

real function expon(x,n)

implicit none

real x, y, z

integer n, k

if (n.lt.0) then

y=1.0/x

else

y=x

end if

z=1.0

k=iabs(n)

do while (k.gt.0)

if (mod(k,2).ne.0) z = z*y

y=y*y

k=k/2

end do

expon=z

return

end

Norm.