Order of commutative mathematical operations - c++

I've into curious question (asking it myself while reading a crude piece of code). Let's look at expression:
double a = c*d*e*2/3*f;
where c, d, e, f are initialized variables of type double. Does standard guarantee that it would be treated as c*d*e*2 (double result) then divided by 3 and multiplied by f (or some similar behavior). Obviously, 2/3 being calculated to 0 is undesirable.
Which paragraph of standard defines that?

Based on the standard
[intro.abstract] - Note 7 (non-normative):
Operators can be regrouped according to the usual mathematical rules
only where the operators really are associative or commutative.
Mathematical rule for MDAS is from left to right (considering the associativity and precedence of operators). So it is evaluated as follows:
(((((c * d) * e) * 2) / 3) * f)

In a word - yes.
The property you're looking for is called operator associativity. It defines how operators of the same precedence (such as * and /) are grouped and ordered when parenthesis aren't present.
In your case, both * and / have the same precedence, and are both left-associative - i.e., they are evaluated from left to right. Which means c would be multiplied by d, then the result by e, then the result by 2 (which would be done with floating point arithmetic, since you're multiplying a double by an int literal), then divided by 3 (again, using floating point arithmetic) and finally multiplied by f.
See this cppreference page for additional information.

Both * and / have the same precedence, and are left-to-right associative, this means that
a*b*c*d
is parsed as
((a*b)*c)*d
and the same is true if you replace any of the * with /.
Source: http://en.cppreference.com/w/cpp/language/operator_precedence

Related

Different result in changing precedence of operator

I am analysis why a.b /c and a/b.c gives different result for a different cases.
Is someone explain me the reason except than the precedence of operator.
int d= a*b/c;
int e=a/b*c;
cout<< d<< " " << e;
Multiplication and division operators do not precede each other. The left-to-right association of multiplicative expressions becomes significant in this case.
It is simply a mathematical fact that a × b ÷ c ≠ a ÷ b × c in most cases.
For example:
10 × 5 ÷ 2
= 50 ÷ 2
= 25
10 ÷ 5 × 2
= 2 × 2
= 4
Also see:
C++ Operator Precedence - cppreference.com
Precedence of product and division is the same. However when they are mixed they are evaluated in pairs from left to right. For instance:
D = a × b ÷ c
Is evaluated as: (a × b) ÷ c
While
D = b ÷ c × a
Is evaluated as (b ÷ c) × a
Mathematically both are equivalent. However in a programming language they might be different. For instance if a, b and c are integers, the division involved is the integer division.
So if a, b and c are greater than 1 and c does not divide exactly the product a × b, then
a × b ÷ c != b ÷ c × a
Since integer division is discarding different amounts on each side of the equation.
Finally, the specific sample expressions that you provide will produce different results even using real numbers since they are mathematically different.
There are 2 concepts related to this matter, Operator Precedence and Associative Order.
When the operators used have different precedence, Operator Precedence comes into play.
But when the operators have same precedence, compiler's associative order comes into play.
Consider this expression,
a*b/c
If the compiler reads it from left-to-right, which is Left-To-Right Associativity, then the expression is evaluated as,
(a*b)/c
If the compiler reads it from right-to-left, which is Right-To-Left Associativity, then the expression is evaluated as,
a*(b/c)
Therefore, the expressions
a*b/c and a/b*c
would be evaluated differently because the compiler is going to either read both from left-to-right or from right-to-left.
In both the cases, the expressions will be evaluated differently.

How is this Precedence operators working?

I know this is silly question but I don't know which step I'm missing to count so can't understand why the output is that of this code.
int i=2;
int c;
c = 2 * - ++ i << 1;
cout<< c;
I have trouble to understanding this line in this code:
c = 2 * - ++ i <<1;
I'm getting result -12. But I'm unable to get it how is precedence of operator is working here?
Have a look at the C++ Operator Precedence table.
The ++i is being evaluated, yielding 3.
The unary - is being evaluated, yielding -3.
The multiplication is being done1, yielding -6.
The bit shift is evaluated (shifting left by 1 is effectively multiplying by two) yielding -12.
The result -12 is being assigned to the variable c.
If you used parentheses to see what operator precedence was doing, you'd get
c = ((2 * (-(++i))) << 1);
Plus that expression is a bit misleading due to the weird spacing between operators. It would be better to write it c = 2 * -++i << 1;
1 Note that this is not the unary *, which dereferences a pointer. This is the multiplication operator, which is a binary operator.
Operator precedence defined the grouping between the operators and their operands. In your example the grouping is as follows
c = ((2 * (-(++i))) << 1);
That's how "precedence of operator is working here" and that's the only thing it does.
The result of this expression is -6 shifted one bit to the left. This happens to be -12 on your platform.
According to your comment in another answer, you mistakenly believe that operator precedence somehow controls what is executed "first" and what is executed "next". This is totally incorrect. Operator precedence has absolutely nothing to do with the order of execution. The only thing operator precedence does, once again, is define the grouping between the operators and their operands. No more, no less.
The order of execution is a totally different thing entirely independent from operator precedence. In fact, C++ language does not define any "order of execution" for expressions containing no sequence points inside (the above one included).

Minus of a variable in C++?

I have this equation:
R= 2*(-I dot N)*N + I
Can I simply type (-I) or something similar, or do I have to multiply I by -1?
C++ has a unary minus operator that performs negation.
- x
This negates x, just like 0 - x or -1 * x would negate x. Note that the - in -1 * x is also the unary minus operator.
You mention in your comment that:
I is a direction vector
If you're using operators on non-native types, you can't assume that they are defined. It depends whether operator overloading has been implemented on the class: if there is a Vector Vector operator-() member function
Also, mathematically speaking, (-I dot N) == -(I dot N) :)

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

operators computing direction

I encountered something that I can't understand.
I have this code:
cout << "f1 * f1 + f2 * f1 - f1 / f2 is: "<< f1 * f1 + f2 * f1 - f1 / f2 << endl;
All the "f"s are objects, and all the operators are overloaded.
The weird this is that the first computation is of the / operator,
then the second * and then the first *; after that, the operator + and at last, operator -.
So basically, the / and * worked from right to left,
and the + and - operators worked from left to right.
I made another test...
I checked this code:
cout << "f1 * f1 / f2 is: " << f1 * f1 / f2 << endl;
Now, the first operator was * and only then operator /.
So now, it worked from left to right.
Can someone help me understand why is there difference in the directions?
10X!
This is yet again a question of the order of evaluation of function parameters - C++ does not specify such an order. Your code is equivalent to:
(f1 * f1) + (f2 * f1) - (f1 / f2)
The three multiply and divide operations can be evaluated in any order. This is perhaps cleraer for named functions:
add(f1*f2,f2*f1)).minus(f1/f2);
The bottom line is that associativity and precedence have nothing to say about the order of evaluation of function parameters and/or sub-expressions. Given the simple expression:
a + b
the C++ (and C) compiler is free to evaluate a first, then b, or b first then a, whether or not the '+' is overloaded.
It is unspecified in what sequence operator arguments will be calculated.
C++ Standard 5/4:
Except where noted, the order of evaluation of operands of individual operators and subexpressions of individual
expressions, and the order in which side effects take place, is unspecified.
Your expression is equivalent to (* and / are operators too, but leave them as is):
operator-( operator+(f1*f1, f2*f1), f1/f2 )
Operator precedence defines the order of operators that have different precedence, so that, e.g., * and / always evaluate before + and -. Then there is the left-to right rule when multiple operators of the same precedence are concatenated.
However, there is (with the exception of logical and ternary operators) no rule about which of an operator's arguments should be evaluated first. The compiler is free to perform the multiplicative operations in any order in pleases before passing them to the additive operators.
In fact, with the expression f() + g() + h(), the compiler is free to call the functions in reverse order, h(), then g(), then f(), then add together the result of f() and g(), and finally add the result of h(). That wouldn't be a very sensible thing to do in most cases, but it's perfectly legal.
User defined operators use the same precedence and associativity rule than buil-in ones.
Rule of precedence state that operators with higher precedence should be executed before those with lower precedence when adjacent in an expression (separated by a single operator).
Associativity rule state in wich order operators should be executed when an expression contains adjacent operators of same precedence.
In your first exemple precedence rule apply, but as associativity is only about adjacent operators the compiler choose in which order he will execute multiply and divide.
In Your second exemple the asociativity rule applies.
Rule of thumb to avoid problems with this kind of rules (that can be somewhat complex):
if unsure use parenthesis or local variables to force order.
avoid side effect when you call function (or user defined operators) because result could be surprising
when redefining operators try to be consistent with maths
http://www.cppreference.com/wiki/operator_precedence
strange behavior, indeed.
But what i would say is that this should not matter, because a * b / c should be equal to a / c * b if you implemented them mathematical-wise
This just looks like simple operator precedence at work.
In your first example, all the multiplication and division must be done before the addition and subtraction. Since the results of the multiplications and divisions are independent, it really doesn't matter what order they're performed, just that the results are used from left to right in the addition and subtraction.
In the second example, the multiplication and division are not independent and must be performed left to right.
You're always getting the correct results based upon operator precedence. THat's all that really matters. The compiler does not guarantee anything about the order of evaluation other than that operator precedence is honored.
Neil is right .
It is matter of operator associativity and precedence.
The expression is evaluated as (f1 * f1) + (f2 * f1) - (f1 / f2) as per the rules suggests and after that it is left to right in second pass . lastly addition and sub. takes place.
second example is simple. * and / have same precedence so we evaluate the expression as per the associativity rules which is left to right hence the order.