# Elevation to power function using class templates

I attached below a small working example of a function that is able to perform x^y. As it is possible to see the base (x) takes double and the power takes an int. As last the main loop will also round up or down the result accordingly.

Not always I have these type of formats, and I could have base as int and power as double or base as long int and power as additional type. How can I improve this function to make it more general with different type format using template template <class identifier> or/and template <typename identifier>?

#include <cmath>

using namespace std;

class Power {
public:
double raiseToPower(double x, int power)
{
double result;
int i;
result = 1.0;
for(i = 1; i <=power; i++){
result = result*x;
}
return result;
}

double floor0(double num)
{
if( (num + 0.5) >= (int(num) + 1) )
return int(num)+1;
else
return int(num);
}
};

int main()
{
double x;
int i;
Power example;
std::cin>>x;
std::cout<<"please enter the integer power that you want this number raised to"<<std::endl;
std::cin>>i;
std::cout<<"rise to power "<<i<<" is equal to "<<example.raiseToPower(x,i)<<std::endl;
std::cout<<"the result rounded is "<< example.floor0(example.raiseToPower(x,i))<<std::endl;
}


Thank for any insight and point to the right direction.

• Is something wrong with std::pow though? – Juho May 9 '19 at 16:30
• @Juho, thank for reading my question, there is nothing wrong with std::pow but I would like to have another way of expressing this type of function or future functions – Emanuele May 9 '19 at 16:37
• The logic you have for raiseToPower currently will only work for positive integer exponents. So before you can meaningfully support other types as exponents, you need to expand that. – Errorsatz May 9 '19 at 20:38
• @Errorsatz, thanks for your comment and for reading the question, how could I modify the function and make it better then? – Emanuele May 9 '19 at 21:21
• Are you from Java? Your functions make more sense being free functions in C++. – L. F. May 10 '19 at 9:01

Don't using namespace, especially a big and growing namespace like std that's not designed for it.

There's no need to include <cmath>. On the other hand, there is a clear need for <iostream>, which has been omitted.

# Structure

There's no need for the Power class; it maintains no state. The functions should simply be free functions, perhaps in a namespace.

# Consider full range of types

raiseToPower() only works with non-negative exponents; it should either accept an unsigned type or be modified to work correctly with negative inputs. Perhaps like this:

    if (power < 0) {
return raiseToPower(1/x, -power);
}


# Improve the algorithm

For large power, the loop is executed many times. We can use binary exponentation to reduce that to log₂ power iterations of the loop.

# Avoid over-complication

floor0() doesn't need that if/else; simply add 0.5 before truncating:

constexpr double floor0(double num)
{
return int(num + 0.5);
}


It might be better to use long or long long there; in any case, you'll still suffer bugs when the value is too big for the integer type. std::floor() doesn't have that problem.

# Validate inputs

If I enter a non-number, I don't get a clear error message. Instead, the program uses uninitialised values, which is Undefined Behaviour. Don't do that; instead check that std::cin is still good before using x or i.

# Avoid std::endl unless you need output flushing

None of the uses of std::endl here are necessary, and we can use \n instead. (Remember that using std::cin flushes the output streams, and returning from main() also flushes outputs).

# Modified code

double raiseToPower(double x, int power)
{
if (power < 0) {
return raiseToPower(1/x, -power);
}

double result = 1.0;
double m = x;

for (;  power;  power /= 2) {
if (power % 2) {
result *= m;
}
m *= m;
}
return result;
}

constexpr double floor0(double num)
{
return int(num + 0.5);
}

#include <iostream>

int main()
{
double x;
int i;
std::cout << "Please enter the number\n";
std::cin >> x;
std::cout << "Please enter the integer power that "
"you want this number raised to\n";
std::cin >> i;
if (!std::cin) {
std::cerr << "Input format error\n";
return 1;
}
auto const result = raiseToPower(x,i);
std::cout << x << " raised to power " << i << " is equal to "
<< result << '\n';
std::cout << "The result rounded is "
<< floor0(result) << '\n';
}

• thank you very much for the very detailed and comprehensive explanation on how to improve the code! Exactly what I was looking for! :) – Emanuele Jun 6 '19 at 20:43