I didn't think these if's would compile but they do:
if (a>>b&&c&&d)
if (month==1,2,3,5,7,9,10)
The first I'm clueless about. In the second statement is the comma supposed to be an (||) or operator ?
Syntax wise was it always this way or was it introduced some time ago ?
I'm using Visual Studio 2010.
if (a>>b && c && d)
it is equal to
if ((a>>b) && c && d)
if the result of a shifted right b times evaluates to a bool, c and d also evaluates to bool respectively, then all these booleans will be AND-ed to each other.
In your context, the all expressions within commas will be evaluated and then the last expression will be passed to if expression:
if (month==1,2,3,5,7,9,10) -> is equal to
if (2,3,5,7,9,10) -> is equal to
if (3,5,7,9,10) -> is equal to
if (5,7,9,10) -> is equal to
if (7,9,10) -> is equal to
if (9,10) -> is equal to
if (10)
which is always true.
It's not suppose to be || or &&. If you want OR or AND write it like below:
if (month==1 || month==2 || month==3 || ....)
or
if (month==1 && month==2 && month==3 && ....)
// Also month can not simultaneously be equal to more than one value!
// then, it's equal to
if (false)
The first if statement would be evaluated like:
if(((a >> b) && c) && d)
Essentially bitshift a by b bits and then logical and with c and then with d
The second is the comma operator which will evaluate the first term and throw it away, then the second, and so on and return the result of the final term. So in our case the statement is equivalent to:
if(10)
which is always true.
Related
According to precedence rules <, >, <=, >= has precedence over !=, ==
I am so confused that how the following statement will be executed
int a=3, b=3;
cout<< (a != b || a <= b);
I know short circuit evaluation and according to precedence rules I guess that compiler will execute a <= b first as it has precedence over != but it is not doing so.
I did little experiment with above statement by changing a <= b-- and changing order of above conditions and it seems that <= and != have same precedence as compiler execute whichever occurred first. Or I am missing something?
Precedence of operators is only relevant to how expressions are bound, not to how they're executed. Execution order is dependent on the "happens-before" relationship and otherwise subject to arbitrary reordering by the compiler.
Relative precedence of two operators also only matters if they are directly adjacent. In a == b <= c, you get a == (b <= c), not (a == b) <= c. In a == b || c <= d, the adjacent pairs are == and || and || and <=. In both cases the comparison operators bind more strongly, so you get (a == b) || (c <= d), making the relative precedence of == and <= irrelevant. If you have a == b + c <= d instead, you first get a == (b + c) <= d, and now you need to compare == and <= again, getting you a == ((b + c) <= d).
As for order of evaluation, || has a rule that its left side is sequenced before its right side (assuming it's not overloaded), because the right side might not get evaluated at all. So the == is executed first. But precedence plays no part at all in this. If you instead had written the non-short-circuiting a != b | a <= b, both sides would eventually get executed (with caveats, see below), but there are no guarantees which side gets evaluated first; precedence does not play a part here.
Caveat: the compiler can still just optimize your code and realize that a != b || a <= b is tautological, and simply replace the entire thing with true.
Precedence is not order of evaluation.
Precedence is about where to put parentheses. a != b || a <= b is parsed as: (a != b) || (a <= b). It's not parsed as like for example: a != (b || (a <= b)) or any other combination of ( ).
After we know where parentheses are, then we can evaluate the expression. The order of evaluation is: (a != b) first. Then || is evaluated. Then, optionally, a <= b is evaluated.
From: https://en.cppreference.com/w/cpp/language/operator_logical
You are looking for the part in ( )
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
So a != b will be evaluated first.
In your case 3 != 3 so the second operand will be evaluated.
if( (5<5) || (5!=5) || (5==5) || (5>5) )
The precedence left to right, so 5<5, goes to next 5!=5 goes to next 5==5 operand if returns true and 5>5 is not evaluated.
As per Microsoft doc,
The operator <= >= < > has higher precedence than the operator != ==. But as you have applied the logical or || operator the expression will be executed from left to right.
It will handle it as ( ( a != b ) || ( a <= b ) ) meaning, first ( a != b ) will be check, after that, logical ||, and if there's need than this expression ( a <= b ) will be checked ( only if the first expression ( a != b ) is wrong).
Suppose I have a bunch of integers (10~20) and need to check if any of them equals 0. What's the most efficient way to do it? I don't want to evaluate a giant if(a=0 || b=0 || c=0 ||...) statement. I thought of if(abc... = 0) but if I remember correctly multiplication isn't a very quick process. Are there any other tricks, such as bit wise operations that would work? I'm trying to think as low level as possible to make this super efficient.
I'm pretty sure the fastest and clearest way to do this is with an explicit test:
int has_zero = !a || !b || !c || !d || !e ...;
Because the || and && are short-circuiting operators in C, evaluation stops as soon as the final result is known, so if (for instance) the b variable is zero, that satisfies the expression as true and stops evaluating the rest.
#AbhayAravinda suggested that !(a && b && c && d ...) might be more efficient, but I don't think so; because this is not so much doing an explicit not operation, but a low-level test-against-zero, this is a really easy test for pretty much any architecture to do reliably. I did a quick look at optimized assembler for both versions and there was no clear winner for performance, but I think the first version is clearer.
If every single cycle matters, then check both versions on your platform, but on my 64-bit Intel system, both gcc and clang do in fact generate the same assembly for both versions (with optimizations turned on).
Simple test code:
int a, b, c, d, e, f;
int test_or()
{
return !a || !b || !c || !d || !e || !f;
}
int test_and()
{
return ! (a && b && c && d && e && f);
}
int main()
{
return test_or() | test_and();
}
Compile this with gcc -S -O testfile.c and look at the resulting .s file.
Test each one in turn. Exploit the short-circuiting property of ||; place the variables in descending order of the probability of each being zero:
if (!a/*most likely to be zero*/ || !b || ...){
// one of them is zero
}
Most people give an answer like:
!a || !b || ...
(where a is the most probable one of being zero)
The idea is that, in case a is zero, then the rest of the sequence is not evaluated (because of not being necessary), which is a kind of optimisation, performed by the compiler.
This turns the question into: does your compiler perform this optimisation or not (and in case of "possibly yes", what are the parameters in order to enforce this)?
Can you tell us which compiler (version) you're working with? This might enable us verifying this.
You may look at the assembler output.
The !a || !b || !c || !d || !e || !f will give you a bunch of cmp and je statements. One pair for each variable. Because of boolean short cut evaluation, it may run very fast. Or not.
The maybe better and deterministic solution is using the bitwise AND operator. If one operand is 0, then the result will be 0. So someting like:
if (a & b & c & d & e & f & g & h & i & j & k)
will result in one mov and then and statements for each variable.
So, if the variable that is 0 is in the 2nd half of the if statement, then the bitweise AND will be faster.
I had the task of finding a logical expression that would result in 1 if and only if a given number n is a multiple of 2019 and is NOT from the interval (a, b).
The textbook gave the following answer and I don't really understand it:
a>=n || b<=n && (n%3==0 && n%673==0)
The thing between those parantheses I understand to be equivalent to n%2019==0, so that's alright. But I don't understand why this works, I mean the && operator has higher priority that the || operator, so wouldn't we evaluate
b<=n && (n%3==0 && n%673==0)
first and only at the end if n<=a? I thought that if I were to do it, I would do it like this:
(a>=n || b<=n) && (n%3==0 && n%673==0)
So I just added that extra set of parantheses. Now we would check if the number is not in the interval (a, b), then we would check if it is a multiple of 2019 and then we would 'and' those to answers to get the final answer. This makes sense to me. But I don't understand why they omitted that set of parantheses, why would that still work? Shouldn't we consider that && has higher priority than ||, so we add an extra set of parantheses? Would it still work? Or is it me that is wrong?
Trying it out shows that the expression as written without the extra parentheses doesn't work:
bool expr(int n, int a, int b)
{
return a>=n || b<=n && (n%3==0 && n%673==0);
}
expr(1000, 2000, 2018) for example evaluates to true, even though it is not a multiple of 2019.
As you pointed out, the logical AND operator && has higher precedence than the logical OR operator || (reference), so the expression is equivalent to:
a>=n || (b<=n && (n%3==0 && n%673==0))
which is always true when n <= a, even if it's not a multiple of 2019.
A clearer expression would be:
(n % 2019 == 0) && (n <= a || n >= b)
Different between '(!server[i].type==-1)' and '(server[i].type!=-1)'
Server is a struct array have type and amount two members.
server[0] type:-1 amount: 100
server[1] type: 0 amount: 50
server[2] type: 1 amount: 50
I want to calculate the sum of amounts of type not -1.
I think these two codes are same
for(int i=0;i<3;i++) {
if(!server[i].type==-1)
total+=server[i].amount;
}
for(int i=0;i<3;i++) {
if(server[i].type!=-1)
total+=server[i].ptime;
}
But i found the first one not work.Can someone tell me why this happen?Thank you very much.
Well server[i].type != -1 is true if server[i].type is not equal to -1.
On the other hand, !server[i].type==-1 due to operator precedence evaluates as (!server[i].type) == -1, which is never going to be true because the left hand side is either going to be 0 or 1, unless server[i].type has operator! overloaded... which I'm assuming is not the case. The equivalent version would be !(server[i].type == -1).
The unary operator ! is the boolean inversion operator, i.e.
!true → false
!false → true
The binary operator != is the "not equal" operator, i.e. the boolean inverse of "equal to"
a != b → true <=> a == b → false
or written slightly differently
(a != b) == !(a == b)
Take note of putting the boolean inverse operator in front of a pair of parentheses. The reason for that is, that the boolean inversion operator has a higher precedence than the boolean equality operator. Which means that !a == b is equivalent to (!a) == b.
In C and by extension C++ every nonzero value is considered boolean true, and zero is boolean false. Also the result of boolean operators is specified to be either 0 (→false) or 1 (→true).
Now let's look at your two different expressions "!a==-1 and a!=-1"
Since ! is a boolean operator the result of !a is defined to be either 0, or 1. So in case a is nonzero, i.e. true (!a) → 0 thus 0==-1 → false as for a being zero (!0) → 1 thereby 1==-1 → false. Hence the expression !a==-1 will always yield false.
a!=-1 on the other hand is comparing the value of a with -1. Its boolean algebra equivalent would be !(a==-1).
Here is a block of code. Can anyone explain what it means to have a pair of numbers enclosed inside parentheses. (This is in C++.)
int a = 2, b = 2, c = 3, d = 1;
if((a,b)<(c,d))
cout<<"case1"<<endl;
else
cout<<"case2";
That's the comma operator; it evaluates the thing on the left, throws the result out, and returns the result on the right. Since evaluating an int variable has no side-effects, that if is semantically equivalent to
if(b < d)
Or if the value are changing or taken as an input by user you can use && (and), || (or) logical operators to sort out your codes
if ((a<c) && (b<d))
or
if ((a<c) || (b<d))
That way you can make cases the way you like. Check about operators here http://www.cplusplus.com/doc/tutorial/operators/