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.
Related
What is the difference between operators associativity and order of evaluation?
I have expected that operator associativity is a precedence of operators which in the same group and have the same precedence, but I cannot understand the difference between operators associativity and order of evaluation
Associativity informs the order of evaluation of the components of an expression, but it does not entirely define it.
Consider this expression: a + b + c. Associativity of + is left-to-right, so we know that this is conceptually equivalent to ((a + b) + c). What this means is that the expression a + b gets evaluated before the addition of that result to c. That informs the order of evaluation.
But this does not entirely define ordering. That it, it does not mean that a or b gets evaluated before c. It is entirely possible for a compiler to evaluate c first, then a and then b, then +ing a and b, and finally +ing that to the result of c. Indeed, in C++14, it is possible for a compiler to partially evaluate c, then evaluate part of a, then some of b, then some of c etc. That all depends on how complex a, b, and c are.
This is particularly important if one of these is a function call: a(x + y, z) + b + c. The compiler can evaluate x, then c, then z, then y, then b, then x + y, then evaluate a, then call the result of that evaluation, then adding that to b, then adding that to c.
In C++, "associativity" refers to the direction in which an operator is applied to its operands, while "order of evaluation" refers to the order in which operands are evaluated. For example, the addition operator (+) has left-to-right associativity, meaning multiple additions in an expression are evaluated from left to right. However, the order of evaluation is not guaranteed to be predictable, and can affect the result of an expression with side effects. Understanding these concepts is important for writing correct and predictable code.
Lets suppose that a = 2^k
is there any difference in terms of performance or correctness between int c = b%a and int c = b & (a-1)?
For two’s complement int and a a power of two, b % a equals b & a-1 if and only if b is non-negative or a multiple of a.
As a consequence, a compiler can replace b % a by b & a-1 only if it knows b is non-negative or knows it is a multiple of a. (In the latter case, it should replace the expression with zero.) On typical current processors, an AND and a subtract instruction will be at least as fast, and often faster, than a remainder (divide) instruction, so b & a-1 is preferred, and the programmer seeking performance should use it if they know the conditions are satisfied, unless they are sure the compiler will generate an AND for b % a or they also want the quotient b/a. (If the quotient is desired, the compiler must generate a divide instruction, and processors typically provide the remainder along with the quotient.)
Of course, the compiler can be assured that b is non-negative by making it an unsigned int. Ensuring the compiler knows that a is a power of two is more complicated, unless a is a constant.
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
Two 32 bit integer values A and B, are processed to give the 32 bit integers C and D as per the following rules. Which of the rule(s) is(are) reversible?
i.e. is it possible to obtain A and B given c and D in all condition?
A. C = (int32)(A+B), D = (int32)(A-B)
B. C = (int32)(A+B), D= (int32)((A-B)>>1)
C. C = (int32)(A+B), D = B
D. C = (int32)(A+B), D = (int32)(A+2*B)
E. C = (int32)(A*B), D = (int32)(A/B)
A few questions about the integer arithmetic. Modular addition forms amathematical structure known as an abelian group. How about signed addition? It's also commutative (that’s where the “abelian” part comes in) and associative, is this forms a n an abelian group?
Given that integer addition is commutative and associative, C is apparently true, because we can retrieve A by (A+(B-B)). What about D? Can we assume that 2 * B = B + B st. B = A+B+B-(A+B)?
And multiplication is more complicated, but I know that it can not be retrieve A if there is an overflow.
This is a quote from 5 [expr] paragraph 4:
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
What makes overflow for unsigned integers work is defined in 3.9.1 [basic.fundamental] paragraph 4:
Unsigned integers shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.
Basically this says that you shall not overflow when using signed integer arithmetic. If you do, all bets are off. This implies that signed integers do not form an Abelian group in C++.
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).