I've got two problems with those that are weirdly sorta opposite each
other.
exponent.
I would recommend against recursion. A recursive algorithm, though it's
easy to do and understand, will be grossly inefficient for the problem.
An iterative one is just as easy:
template<typename T>
T exponentiate(T base, int exp)
{
T ret = 1;
for( ; exp>0 ; --exp)
ret *= base;
return ret;
}
It's very possible that your compiler will be able to convert your
recursive solution to an iterative one, but this is a fairly
substantial optimization at little cost, and do you really want to
trust that your compiler will recognize that this is optimizable? (I
just tried it under gcc under Solaris and I don't know enough Sun
assembly to know if it did.)
And for powers of 2, how about using a shift function? 16 << 1.
On the other hand, this seems like the sort of optimization that you
DON'T want to do. 16 << 1 is not that much faster than 16 * 2. Unless
you're doing it a whole lot or running in a very very very tight
environment it won't make any difference. Second, as much as it will
help, I will almost gurantee that the compiler is much more likely to
optimize 16 << 1 than it is to find tail recursion. This is the sort of
optimization that can probably be implemented even in debug builds.
Third, you've reduced readability. Maybe not much for something like 'x
= 16 << 1', but quick, what is the value of '3 << 1 + 1'? Is it 7 ('(3
<< 1) + 1') or 12 ('3 << (1+1)')? I bet you had to think about that
much more than 3 * 1 + 1. Oh, and it's a different answer. So you can't
just substitute '<<1' everywhere you see '*2'. (MSVC warns about it:
"warning C4554: '<<' : check operator precedence for possible error;
use parentheses to clarify precedence".)