0

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.

Jordan
  • 305
  • 3
  • 13

6 Answers6

11

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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Quite true. A good reason why a lot of languages don't even support operator overloading. – AaronF Jul 02 '14 at 16:54
  • 1
    @AaronF: I'm not sure I agree it's a *good* reason to forego operator overloading entirely. It's not universally applicable, but code using (for one example) big integers in C++ vs. Java or C provides a pretty strong argument that operator overloading can provide major benefits. You just have to be judicious in how you use it. – Jerry Coffin Jul 02 '14 at 17:01
3

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();
}
AaronF
  • 2,841
  • 3
  • 22
  • 32
  • 1
    In a real world case, you'd want to pass Number class to the ^ operator, and overload all the standard math operators as well. If you're wanting to deal with large numbers, (as you might with an implementation of MATLAB), may I suggest you look into "infint", which allows you to calculate with as big a number as you want: https://code.google.com/p/infint/ I've found it very helpful for some things. – AaronF Jun 28 '14 at 05:00
  • 3
    I pity the next programmer who has to maintain the code written with this monstrosity. – T.C. Jun 28 '14 at 05:08
  • 1
    Yes, thanks. I'm well aware of the potential design problems with building math software around ad-hoc number classes. However, Jordan's question specifically regarded the technical aspects of using the XOR operator as a power operator, which I believe I answered reasonably. I also offered an established alternative for dealing with large numerical calculations (infit). You have a great reputation (3200+), so if you have a superior idea, please share it. I would happily learn from somebody with more experience. (And yes, I read your post before writing my answer. :) ) – AaronF Jun 28 '14 at 05:18
  • Another benefit of infint and other big integer libraries is that you don't have to deal with binary approximations. Unfortunately, many of them are also significantly slower, (depending on how the data is modeled), so you'll have to weigh your use cases. – AaronF Jun 28 '14 at 05:23
  • 1
    @AaronF My view is that the answer to the question "How do I shoot myself in the foot?" should be "Don't.", and not "Load your gun, point it towards your foot, and pull the trigger." – T.C. Jun 28 '14 at 05:52
  • Just prototyping some code here, not software for a pace maker :p – Jordan Jun 28 '14 at 05:54
  • It's won't work with unchanged code unless you have `operator float&() { return _num; } operator float() const { return _num; }`. @T.C. I think everyone understands your concerns, but this may be a reasonable approach in certain very limited circumstances - especially for a prototype - and certainly such experimentation is part of the fun of mastering C++. All you can do is warn, offer concrete examples of dangers that might not have been thought of, and offer alternatives.... ;-) Here, a `sed` command to do a global replace might be just the thing.... – Tony Delroy Jun 28 '14 at 06:15
2
  • 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 ...
}
Community
  • 1
  • 1
quantdev
  • 23,517
  • 5
  • 55
  • 88
2

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.)

T.C.
  • 133,968
  • 17
  • 288
  • 421
0

pow() in the cmath library. More info on

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

Jay Nirgudkar
  • 426
  • 4
  • 18
0

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

Shahriar.M
  • 818
  • 1
  • 11
  • 24