fbpx

C++: Exponentiation Operator

Bjarne-stroustrup
 

Most all programming languages have a built-in implementation of exponentiation. Re-implement integer exponentiation for both intint and floatint as both a procedure, and an operator (if your language supports operator definition).

If the language supports operator (or procedure) overloading, then an overloaded form should be provided for both intint and floatint variants.

While C++ does allow operator overloading, it does not have an exponentiation operator, therefore only a function definition is given. For non-negative exponents the integer and floating point versions are exactly the same, for obvious reasons. For negative exponents, the integer exponentiation would not give integer results; therefore there are several possibilities:

  1. Use floating point results even for integer exponents.
  2. Use integer results for integer exponents and give an error for negative exponents.
  3. Use integer results for integer exponents and return just the integer part (i.e. return 0 if the base is larger than one and the exponent is negative).

The third option somewhat resembles the integer division rules, and has the nice property that it can use the exact same algorithm as the floating point version. Therefore this option is chosen here. Actually the template can be used with any type which supports multiplication, division and explicit initialization from int. Note that there are several aspects about int which are not portably defined; most notably it is not guaranteed

  • that the negative of a valid int is again a valid int; indeed for most implementations, the minimal value doesn’t have a positive counterpart,
  • whether the result of a%b is positive or negative if a is negative, and in which direction the corresponding division is rounded (however, it is guaranteed that (a/b)*b + a%b == a)

The code below tries to avoid those platform dependencies. Note that bitwise operations wouldn’t help here either, because the representation of negative numbers can vary as well.

emplate<typename Number>
Number power(Number base, int exponent)
{
	int zerodir;
	Number factor;
	if (exponent < 0)
	{
		zerodir = 1;
		factor = Number(1)/base;
	}
	else
	{
		zerodir = -1;
		factor = base;
	}

	Number result(1);
	while (exponent != 0)
	{
		if (exponent % 2 != 0)
		{
			result *= factor;
			exponent += zerodir;
		}
		else
		{
			factor *= factor;
			exponent /= 2;
		}
	}
	return result;
}

SOURCE

Content is available under GNU Free Documentation License 1.2.