Jordan
Jordan

Reputation: 305

How to use a Caret "^" in C++ for Exponentiation

I am currently rewriting MATLAB code into C++ code. To have the ability to raise "a" to the power of "b" just by typing "a^b" would make my life so much easier as this is how much of the original code was written in MATLAB.

Is there a way to do this? (I am using primitive types)

I'll happily accept a solution that does NOT involve parenthesis and commas like the pow(a,b) method.

Thanks in advance.

Upvotes: 0

Views: 8341

Answers (6)

Jerry Coffin
Jerry Coffin

Reputation: 490663

While it is possible to overload ^ to do exponentiation, you shouldn't. It's a bad idea.

@AaronF's answer shows how ugly the code to do this is, but that's only the tip of the iceberg. The real problem comes when you try to actually use this in real code. The problems stem from one simple fact: overloading an operator changes the actions carried out by that operator, but does not affect either the precedence or associativity of that operator. In the case of ^, both the precedence and the associativity are completely wrong for exponentiation.

precedence

In C++, the ^ operator has quite low precedence. Exponentiation should have very high precedence. For example, an expression like x^y*z would normally mean xyz--but what it will mean in C++ is xyz. In fact in C++, ^ has precedence even lower than addition and subtraction, so even x^y+z comes out wrong--it means xy+z instead of the xy+z that you'd want/normally expect.

Associativity

Exponentiation is right associative--but in C++, the ^ operator is left associative. For example, given an expression like x^y^z, what you'd want/expect would be for it to mean xyz, but what you'll get is (xy)z (equivalent to xyz).

Result

These mean that if you do overload operator^ to do exponentiation, you'll only have gotten away from using the name pow. You will not get away from most of the parentheses; in any non-trivial expression, you'll still need parentheses to force the proper precedence and associativity, because as outlined above, the precedence and associativity C++ assigns to operator^ are both entirely wrong for exponentiation.

Conclusion

Although you can overload operator^ to do exponentiation, this is one of those places where discretion is the better part of valor. When you overload operators in C++, you really have three factors to take into account: the name, the precedence and the associativity. For a good operator overload, all three should be right. It's sometimes reasonable to do an overload where only two out of three are right, and the third isn't too far off. In this case, only one out of the three is even close to right; the other two are completely wrong.

Don't do this. It's a bad idea.

Upvotes: 13

AaronF
AaronF

Reputation: 3101

The following works, but you have to compile with the c++11 standard (g++ -std=c++11 *.cpp): You can't use the XOR (^) operator for exponents with primitives. You have to overload it within a class.

#include <iostream>
#include <cmath>
#include <ctgmath>

using namespace std;

class Number {
private:
    float _num;
public:
    Number(float num) : _num(num){}
    Number operator^(const float& num) {
        return Number(pow(_num,num));
    }
    float get() {
        return _num;
    }
};

int main() {
    Number a = Number(5);
    Number b = a^7;
    cout << b.get();
}

Upvotes: 3

T.C.
T.C.

Reputation: 137394

You can't do this for primitive types. You'll need to use std::pow. You can do it for user-defined types by overloading the ^ operator, but it may not be a good idea unless XOR makes no sense for your type.

(10 minutes after I say this someone will come up with a horrible, horrible hack for primitive types with a user-defined type, implicit conversions, a user-defined literal, and an overloaded ^ operator.)

Upvotes: 2

quantdev
quantdev

Reputation: 23813

  • For primitive types (your case) :

    In C and in C++, ^ is the bitwise XOR (exclusive-or) operator. You should use std::pow to raise a number to a power.

  • For non primitive types, you could however overload operator^ (but it is discouraged since you would go against the usual meaning of this operator)

Example:

MyClass operator^(const MyClass& t1, const MyClass& t2)
{
    //return ...
}

Upvotes: 2

Shahriar.M
Shahriar.M

Reputation: 898

it seems you are looking for someone to say write a^b :D you should use predefined functions or write a new one ;)

Upvotes: 0

iceyb
iceyb

Reputation: 436

pow() in the cmath library. More info on

http://en.cppreference.com/w/cpp/numeric/math/pow

Upvotes: 0

Related Questions