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

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.

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.

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();
}

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

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

pow() in the cmath library. More info on
http://en.cppreference.com/w/cpp/numeric/math/pow

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

Related

De Morgan's Law optimization with overloaded operators

Every programmer should know that:
(De Morgan's Laws)
Under some circumstances, in order to optimize the program, it may happen that compiler modifies (!p && !q) to (!(p || q)).
The two expressions are equivalent, and it makes no difference evaluating the first or the second.
But in C++ it is possible to overload operators, and the overloaded operator may not always respect this property. So transforming the code this way will actually modify the code.
Should the compiler use De Morgan's Laws when !, || and && are overloaded?
Note that:
Builtin operators && and || perform short-circuit evaluation (do not evaluate the second operand if the result is known after evaluating the first), but overloaded operators behave like regular function calls and always evaluate both operands.
...
Because the short-circuiting properties of operator&& and operator|| do not apply to overloads, and because types with boolean semantics are uncommon, only two standard library classes overload these operators ...
Source: http://en.cppreference.com/w/cpp/language/operator_logical
(emphasis mine)
And that:
If there is a user-written candidate with the same name
and parameter types as a built-in candidate operator function, the built-in operator function is hidden and
is not included in the set of candidate functions.
Source: n4431 13.6 Built-in operators [over.built] (emphasis mine)
To summarize: overloaded operators behave like regular, user-written functions.
NO, the compiler will not replace a call of a user-written function with a call of another user-written function.
Doing otherwise would potentially violate the "as if" rule.
I think that you have answered your own question: no, a compiler can not do this. Not only the operators can be overloaded, some can not be even defined. For example, you can have operator && and operator ! defined, and operator || not defined at all.
Note that there are many other laws that the compiler can not follow. For example, it can not change p||q to q||p, as well as x+y to y+x.
(All of the above applies to overloaded operators, as this is what the question asks for.)
No, in that case the transformation would be invalid. The permission to transform !p && !q into !(p || q) is implicit, by the as-if rule. The as-if rule allows any transformation that, roughly speaking, cannot be observed by a correct program. When overloaded operators are used and would detect the transformation, that automatically means the transformation is no longer allowed.
Overloaded operators per se are just syntactic sugar for function calls; the compiler itself is not allowed to make any assumption about the properties that may or may not hold for such calls. Optimizations that exploit properties of some specific operator (say, De Morgan's for boolean operators, commutativity for sums, distributivity for sum/product, transformation of integral division in an appropriate multiplication, ...) can be employed only when the "real operators" are used.
Notice instead that some parts of the standard library may associate some specific semantic meaning to overloaded operators - for example, std::sort by default expects an operator< that complies to a strict weak ordering between the elements - but this is of course listed in the prerequisites of each algorithm/container.
(incidentally, overloading && and || should probably be avoided anyway since they lose their short-circuiting properties when overloaded, so their behavior becomes surprising and thus potentially dangerous)
You are asking whether the compiler can arbitrarily rewrite your program to do something you did not write it to do.
The answer is: of course not!
Where De Morgan's laws apply, they may be applied.
Where they don't, they may not.
It's really that simple.
Not directly.
If p and q are expressions so that p does not have overloaded operators, short circuit evaluation is in effect: expression q is going to be evaluated only if p is false.
If p is of non-primitive type, there is no short circuit evaluation and overloaded function could be anything - even not related to the conventional usage.
Compiler will do its optimizations in its own way. Perhaps it might result de Morgan identities, but not on the level of if condition replacement.
DeMorgan's laws apply to the semantics of those operators. Overloading applies to the syntax of those operators. There is no guarantee that an overloaded operator implements the semantics that are needed for DeMorgan's laws to apply.
But in C++ it is possible to overload operators, and the overloaded operator may not always respect this property.
Overloaded operator is no longer an operator, it is a function call.
class Boolean
{
bool value;
..
Boolean operator||(const Boolean& b)
{
Boolean c;
c.value = this->value || b.value;
return c;
}
Boolean logical_or(const Boolean& b)
{
Boolean c;
c.value = this->value || b.value;
return c;
}
}
So this line of code
Boolean a (true);
Boolean b (false);
Boolean c = a || b;
is equivalent to this
Boolean c = a.logical_or(b);

Operator priority with operator overload?

I used operator overloading for my own Bignum header, and there are some operator priority problem.
Compiler says there is some error when I do bignum+int.
(My Bignum class name is 'bignum'. Don't mind that)
Here is my class definition:
operator long long(void) const {
return atoll(num.c_str());
}
operator +(bignum b) {
//c=this+b
return c;
}
And here is the case that error happens:
bignum a(1);
int b=1;
bignum c = a+b; //this is the case
ERRORS
line 7 : IntelliSense: "+" More than one of the operators is
consistent with the operand. Built-in operators "arithmetic +
arithmetic" Function "minary::bignum::operator+(minary::bignum
b)" The operand format is minary::bignum +
int. c:\Users\Secret\Documents\Visual Studio
2013\Projects\Calculator\Calculator\Source.cpp 11 3 Calculator
Thanks in advance.
The easiest approach is to make the conversion to integers explicit: many implicit conversions cause problems anyway. Sometimes implicit conversions are useful but if you want to deal with mixed type arithmetic they tend to be more a problem than help:
class bignum {
// ...
explicit operator long long() const { ... }
// ...
};
Making the conversion operator explicit is a C++11 feature. Your class also seems to have an implicit conversion from integral types to bignum, i.e., a corresponding constructor. Prior to C++11 you could only make these constructors explicit. This may be another option to deal with the ambiguity but it would have the effect that the conversion to long long and the built-in integer addition is used. My guess that you want a bignum as a result which requires that there is no suitable conversion to an integral type.
Note that the question has nothing to do with operator priority: for any given expression the compiler determines which overloads are the best fit (roughly: require the least amount of implicit conversions). If it finds multiple equally good candidates it considers the program to be ambiguous and asks for the ambiguity to be sorted out.

Using / to create a simple rational number object

I have a bunch of data in the form of extremely long equations that includes rational numbers in the form of (a/b) where a and b are integers. I made a simple class that stores rational numbers with corresponding arithmetic operators.
I'm trying to write some code that is able to recognize the form (a/b) and construct an instance of that class with the corresponding numerator and denominator. I would much prefer to conserve the original form of input (a/b). Is it possible to overload the / operator such that (a/b) will return a rational number object? (If not, any ideas for a workaround?)
Example piece of very simplified code:
Param A;
Param B;
(3/5)*A*A + (1/3)*B*B
My Param class has a well-defined multiplication with itself and with the rational number class. I just need the code to recognise (3/5) and (1/3) as instances of a rational number.
No; you can only overload operators if at least one operand is a user-defined type. You can't overload operator/ where both operands are int or any other built-in type.
The closest you can get is rational(a)/b. Whether or not that's better than rational(a,b) is up to your aesthetic judgement.
In C++11 or later, you could muck around with user-defined literals and write things like 3_r/4; but I wouldn't.
No, you can't write Rational operator/(int, int). Because you can't redefine / for ints.
The direct answer is no: operator overload requires at least one user-defined type (otherwise, they would clash with existing operators).
As for workarounds, there are plenty available:
you may use a function: rational(a, b)
you may use a proxy object: MyInt(a) / MyInt(b), this introduces a user-defined type so you can overload the operator / on that type
you may use the C++11 user-defined literals to wrap integers into a proxy class, and overload the operator / on that: 1_i and Rational operator/(MyInt, MyInt)
Which solution you use will depend on the specific constraints you have.

Are assignment operators "required" to return?

According to the C++ standard, can I be sure that assignment operators for built-in variables return (the original value)?
Or is this implementation dependent (yet simply have most popular compilers implemented this)?
Yes, it is guaranteed:
5.17 Assignment and compound assignment operators
The assignment operator (=) and the compound assignment operators all group
right-to-left. All require a modifiable lvalue as their left operand
and return an lvalue referring to the left operand.
This applies to built-in types. With user-defined types it can return anything.
It depends on what you mean by "the original value".
For example:
#include <iostream>
int main() {
int i;
std::cout << (i = 1.9) << "\n";
}
prints 1. The assignment expression yields the new value of the LHS (namely 1), not the "original value" of the RHS (1.9).
I'm not sure whether that's what you meant to ask about.
According to the C++ standard, can I be sure that assignment operators for build in variables return (the original value)?
Edit I get it now, I think. Yes: you can be sure that the built-in types return the original value by reference after operator=, *=, /=, -=, +=, ^=, ~=, &= and |=.
"For build in variables" is a bit cryptic to me. However,
X makeX()
{
return X();
} // must have accessible copy constructor
// ...
X x;
x = makeX(); // ... _and_ assignment operator
Or is this implementation dependent
It should not be (edit see standard reference by UncleBens)
Yes. It is guaranteed that all assignments and augmented assignments on predefined types work that way.
Note however that user defined types assignments or augmented assignments can instead for example return void. This is not good practice and shouldn't be done (it raises the surprise effect on users - not a good thing), but it's technically possible so if you are writing for example a template library you should not make that assumption unless it's really important for you.
Yes. Operator semantics will simply not work otherwise.

Expression evaluation in C/C++ doesnt follow BODMAS rule?

When a expression is evaluated in C/C++, does it follow BODMAS [Bracket open Division Multiply Addition Substraction] rule? If not then how they are evaluated?
EDIT: More clearly, If the following expression is evaluated according to BODMAS rule,
(5 + 3)/8*9
First what is in brackets is processed.
8/8*9.
Then Division is done.
1*9
And then multiplication and so on.
There are far more operators than that. You can find a precedence tables for C++ and C.
But yes, you'll find it respects that. (Though I'm not sure it's exactly what you've said...)
There are two answers to this question.
One is that C++ does follow standard mathematical precedence rules, which you refer to as BODMAS. You can see the order in which C++ associates all its operators here.
However, if any of the expressions involved in the operation have side effects, then C++ is not guaranteed to evaluate them in what one might consider to be standard mathematical order. That's sort of an advanced topic, however.
Other people have given you links to operator precedence lists. These are well and good. However, if you need to look at an operator precedence table to determine what your code tells computers to do, please take pity on your code's maintainers (including future you) and just use parentheses. It makes your intention much clearer and saves time and heartache in the long run.
C++: http://msdn.microsoft.com/en-us/library/126fe14k.aspx
C#: http://msdn.microsoft.com/en-us/library/aa691323(VS.71).aspx
C applies the operators in arithmetic expressions in a precise sequence determined by the following rules of operator precedence, which are generally the same as those in algebra:
Operators in expressions contained within pairs of parentheses are evaluated first. Parentheses are said to be at the “highest level of precedence.” In cases of nested, or embedded, parentheses, such as
( ( a + b ) + c )
the operators in the innermost pair of parentheses are applied first.
Multiplication, division and remainder operations are applied next. If an expression contains several multiplication, division and remainder operations, evaluation proceeds from left to right. Multiplication, division and remainder are said to be on the same level of precedence.
Addition and subtraction operations are evaluated next. If an expression contains several addition and subtraction operations, evaluation proceeds from left to right. Addition and subtraction also have the same level of precedence, which is lower than the precedence of the multiplication, division and remainder operations.
The assignment operator (=) is evaluated last.
I found an expression that doesn’t follow “BODMAS”. Here is my c program for your reference
#include <stdio.h>
int main() {
int a = 6;
int b = 4;
int c = 2;
int result;
result = a - b + c; // 4
printf("%d \n", result);
result = a + b / c; // 8
printf("%d \n", result);
result = (a + b) / c; // 5
printf("%d \n", result);
return 0;
}