Example:
Operation 1:
d= c | y | z | a<<3 | b <<3 | x;
Operation 2:
m = c|y|z|x;
d = m | a<<3 | b<<3;
does operation 1 and operation 2 yield same results in C?
To answer the question in your title:
Are leftshift and OR operators commutative in C?
the | bitwise-or operator is commutative, but the << operator is not (a<<3 and 3<<a are quite different).
That doesn't appear to be what you meant to ask, though. To answer the body of your question, since << has higher precedence than | (i.e., << binds more tightly), you can think of a<<3 and b<<3 as if they were primary or parenthesized expressions. In effect, you have multiple subexpressions joined by | operators. Rearranging them should have no effect; your two code snippets should behave identically (except that the second one stores a value in m, which doesn't exist in your first snippet).
This assumes that all the variables you're using are of the same type. If they're not, then storing the intermediate value in m might involve a conversion which could alter the results. This probably doesn't apply in your case, but since you didn't show us any declarations it's impossible to be sure of that.
In this case, it should provide the same results since (a) there are no side effects (e.g. built-in pre- or post-increments or decrements), and (b) the << operator has higher precedence than |.
So, the << operations will occur before the | operations.
It's not a question of commutativity, but a question of precedence between operators. Although it does help that | itself is commutative since your choices do change the order in which expressions are or'ed together.
Related
I would like to transform an expression so that all negation operators are propagated down to the literals. So ~(a | b) becomes ~a & ~b. Does anyone have a solution for this?
from pyeda.boolalg.expr import expr
formula = "~(a | b)"
e = expr(formula, simplify=False)
There are a pair of methods to switch back and forth between the conjunction and disjunctive normal forms.
.to_dnf()
.to_cnf()
try,
>>> e.to_dnf()
And(~a, ~b)
Suppose you have a C line of code &x->y->z (doesn't matter what the x/y/z's are). What is the order of evaluation here? I see that -> takes precedence over & in https://en.cppreference.com/w/c/language/operator_precedence. So is this evaluation sequence correct?
x->y is evaluated, and with that result
(x->y)->z is evaluated, and with that result
&((x->y)->z) is evaluated
If this is incorrect, can you tell me what the correct order is?
You are right this is the correct order. explination below:
&x->y->z
if we look in your expression above no matter what is x,y and z. we see that its contained from arrow -> operators or more technicaly speeking (Structure and union member access through pointer) and the address operator &.
In c programing there is the precedence and associativity for all operators. when we come to expression that we have 2 operators with the same precedence then we need to look at the associativity inorder to know what expression we need to evaluate first.
your expression have 2 -> operators and one & operator. -> operator is in the higest (precedence 1) precedence group of operators (he is not alone in this group see the table below). and & in the second higest group (precedence 2) and he is not alone in this group. so operator -> must be evaluated first. but where to start? here comes the associativity. for group 1 in the table below, we evaluates from left to right.
SO the order of the evaluation is:
x->y : evaluate first. for example lets assume its evaluates to P. (x->y=P)
P->z OR (x->y)->z: evaluates after the first (we are going from left to right folowing the associativity rule).
&((x->y)->z) : only now we evaluate the & operator and this will be the final result.
see the link below for C Operator Precedence
First of all, "precedence" doesn't mean order of evaluation . It refers to the association of operands with operators. For example in f() + g() * h(), the three function calls could occur in any order; saying that * has higher precedence is saying that the two operands of * are g() and h(). The compiler might call all three functions, and then multiply the results of the g and h calls, and then add the result of the f call.
In &x->y->z things are easier because the second operand of -> (and .) isn't an expression. It's an identifier that names a class member. So the second operand isn't evaluated, really.
The precedence rules, or grammar table, tells use that the operand of the unary & operator is x->y->z.
To understand x->y->z, clearly it is not the case that we are looking for a member of the struct pointed to by x whose name is "y->z" since that is not a valid identifier. That would not be a valid syntax parse. So it can only mean that ->z is applied to the result of x->y.
You are exactly correct.
The -> operator has the highest precedence and groups from left to right. So that gives you &((x->y)->z).
In C we often say that the operators are left-associative and right associative,
A left-associative operator is for example which starts from the left side and ends on the right of the user.
If for example in case of assignment operator x=y; for x=5 and y=20, is like saying put value of y in the x, that seems very legitimate.
but in cases like if(x>y), '>` operator has left associativity.
Means it computes Is x greater than y? FALSE.
But, why we go like this we can also say it reading from right associativity
Is y smaller than x? FALSE
Why use left associativity when the output comes same in both cases?
For a ternary operation as Mat says.
The answer to x>y>z really depends on the direction, the answer will vary from right to left , to left to right. but that is because of different comparisons done at different stage.
Both the answers will evaluate a value, but why do we say that we will chose only the one with left associativity
You are confused about operator precedence and operator associativity.
Operator associativity only applies with operators with the same precedence. For example:
1 - 2 + 3
+ and - have the same precedence, and they are left-associative, which means the above is equivalent to:
(1 - 2) + 3
The associativity concept come in play only when the expression has more than one operator. It is a property of the operator in the expression, not the operands. It define how brackets are inserted, not what the operator means.
operator : Some R
expression : x R y R z
left to right : (x R y) R z
right to left : x R (y R z)
edit:
Reference of operator associativity in C
You're confused between the Associativity and Readability.
Why use left associativity when the output comes same in both cases?
This is true for the readability but not for all the evaluations of expressions.
Consider:
x=10, y=20, z=10
Now, left to right associativity:
x<y<z => (x<y)<z => (10<20)<10 => (1<10) =>TRUE
Now, right to reft associativity:
x<y<z => x<(y<z) => 10<(20<10) => (10<0) =>FALSE
Now, the concept of associativity arrives only when there are multiple existence of same operator.
I want to write a truth table evaluator for a given formula like in this site.
http://jamie-wong.com/experiments/truthtabler/SLR1/
Operators are:
- (negation)
& (and)
| (or)
> (implication)
= (equivalence)
So far I made this
-(-(a& b) > ( -((a|-s)| c )| d))
given this formula my output is
abdsR
TTTT
TTTF
TTFT
TTFF
TFTT
TFTF
TFFT
TFFF
FTTT
FTTF
FTFT
FTFF
FFTT
FFTF
FFFT
FFFF
I am having difficulties with the evaluating part.
I created an array which in I stored indises of parenthesis if it helps,namely
7-3, 17-12, 20-11, 23-9, 24-1
I also checked the code in http://www.stenmorten.com/English/llc/source/turth_tables_ass4.c
,however I didn't get it.
Writing an operator precedence parser to evaluate infix notation expressions is not an easy task. However, the shunting yard algorithm is a good place to start.
I am learning about left shift operators and for multiplying a number with 10 I am using this code.
long int num=a<<3+a<<1;
so that no. a first multiplies with 8 and then with 2 and on adding gets a*10 which is stored in num.
But its giving some strange result like for 5 its 2560, for 6 its 6144.
Can anyone please explain whats wrong in that implementation?
You have a problem with precedence - the order operators are performed. + binds more tightly than <<, so:
a<<3+a<<1
actually means: a << (a+3) << 1
for 5 that is 5 << 8 << 1 which is 2560 :)
You need: (a<<3) + (a<<1)
See: http://www.swansontec.com/sopc.html for clarification.
The format you are using actually goes this way..
num=a<<(3+a)<<1;
make some difference between the two application of shift operators by using parenthesis like
num=(a<<3)+(a<<1);
What about warning: suggest parentheses around ‘+’ inside ‘<<’
+ is processed before <<.
Use (a<<3)+(a<<1)
<< operator has less precedence than + operator (Thumb rule Unary Arthematic Relational Logical )
so use braces
int num = (a<<3) + (a<<1);