This question already has answers here:
C# conditional AND (&&) OR (||) precedence
(6 answers)
Closed 3 years ago.
I'm going through some C# coding exercises and have run into some operator logic that's stumped me.
The following line of code evaluates to false:
int a = 40, int b = 50;
if (a >= 20 && a <= 30 && (b < 20 || b > 30))
{
return a;
}
However, if I remove the brackets from inside the if statement, it evaluates to true.
if (a >= 20 && a <= 30 && b < 20 || b > 30)
{
return a;
}
Can anyone explain what I'm missing? Given that a isn't between 20 and 30, shouldn't it return false? I don't understand why putting the b portion of the if statement in brackets makes it evaluate to false.
Is it evaluating everything prior to "b > 30" as a single condition?
This is all to do with operator precedence.
Just like how * are evaluated first before + (we say * has a higher precedence than +), && is evaluated before ||, as specified.
In the first code snippet, you used brackets to "override" this precedence, making the || part evaluate first, just like how you can add parenthesis to the expression 1 + 2 * 3 to make it evaluate to 9 instead of 7.
a >= 20 && a <= 30 && (b < 20 || b > 30)
^^^^^^^^^^^^^^^^^
this part first
which becomes:
a >= 20 && a <= 30 && true
^^^^^^^ ^^^^^^^
now these parts
which becomes:
false && false && true
resulting in false.
In the second example however, there are no parentheses so the expression is evaluated according to the normal precedence rules:
a >= 20 && a <= 30 && b < 20 || b > 30
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This part first
Which becomes:
false || b > 30
^^^^^^
then this
which becomes:
false || true
resulting in true.
If you look at the second part where you have removed the parenthesis, it is now divided into two subparts.
First one being : a >= 20 && a <= 30 && b < 20 This evaluates to false.
First one being : b > 30 This statement evaluates to true.
So at the end you have something like this
F || T from both the statements which should eventually give you true as end result
Related
I have this line of code:
bool existsbuy = pricelist.Exists(element => (element <= TPbuyRange) && (element >= Convert.ToDouble(JsonResP.prices[0].closeoutBid)));
Which does not work as expected, it gives me always false.
And I modified to this, which works just fine, it gives me the boolean results as it should:
bool existsbuy1 = pricelist.Exists(element => (element <= TPbuyRange) );
bool existsbuy2 = pricelist.Exists(element => (element >= Convert.ToDouble(JsonResP.prices[0].closeoutBid)));
Then I have this one, which is very similar to the first line, and which works fine too:
bool existssell = pricelist.Exists(element => element >= TPsellRange & element <= Convert.ToDouble(JsonResP.prices[0].closeoutBid));
So I don't get it, what is wrong here?
Consider this:
list = 10,20,30
list.Exists(e => e < 20 && e > 20); //false, no element is less than 20 and also greater than 20
Versus
list.Exists(e => e < 20); //true, element 10 is less than 20
list.Exists(e => e > 20); //true, element 30 is greater than 20
Your other one that works might be this:
list.Exists(e => e < 30 && e > 10); //true, element 20 is less than 30 and also greater than 10
Without knowing what your values are we can't say exactly but this will be the reason
I would also point out that because your Convert.ToDouble(...) is effectively a constant you should do it outside of the LINQ lambda
If the separate conditions both return true, that suggests that the list contains at least one item that satisfies the condition element <= TPbuyRange and at least one item that satisfies the condition element >= Convert.ToDouble(JsonResP.prices[0].closeoutBid)). However, if the joint condition does not return the same value as existsbuy1 && existsbuy2, that suggests that no item in the list satisfies both conditions at the same time.
I have a datetime definition that I do not know how to use of. What exactly is the expression between the <> signs? it returns Boolean but how?
bool x= DateTime.Now.AddDays(20) <DateTime.Now && DateTime.Now.AddDays(10)> DateTime.Now;
Format it differently and it will be easy to see that it's two less than/greater than signs:
bool x = DateTime.Now.AddDays(20) < DateTime.Now
&& DateTime.Now.AddDays(10) > DateTime.Now;
bool x = DateTime.Now.AddDays(20) < DateTime.Now //(1)
&& DateTime.Now.AddDays(10) > DateTime.Now; //(2)
To English:
(1): Is (Today + 20 days) smaller than Today?
// We have False
(2): Is (Today + 10 days) greater than Today?
// We have True
And Finally (1) && (2) will return your result x
// We have x = True && False = False
What exactly is the expression between the <> signs? it returns Boolean but how?
As already mentioned in the code that you posted < and > and && are operators and not tags
the first < is a "less than" relational operator
the last > is a "greater than" relational operator
These operators compare the operands at each side of the operator and return true or false.
the middle operator && is called The conditional-AND operator and it
performs a logical-AND of its bool operands
This is why the whole statement returns bool
I'm making a game in unity, and I have this 'if statement' that by every 5 waves my shop menu will become visible. The code does work, but I am certain I'm doing something wrong or could do something better!
if (waveCount == 5 || waveCount == 10 || waveCount == 15 || waveCount == 20 || waveCount == 25 || waveCount == 30 || waveCount == 35 || waveCount == 40 || waveCount == 45 || waveCount == 50)
{
// yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
As you can see the 'if statement' not that good, normally it continues all the way to waveCount == 100 but i cut that out. There must be a simpler or cleaner way to do this :/ but i just can't wrap my head around it :(
Edit 1:
Thanks, I didn't know much about modulo, know I know what I have to read about :)
You can use modulo operation:
if (waveCount % 5 == 0)
Yes, there are indeed simpler ways of doing this. If you use a little bit of maths and logic, you can figure this out.
Since you want to check whether the value of waveCount is a multiple of 5, you can use % to get the reminder of waveCount / 5. If that reminder is 0, waveCount is a multiple of 5.
if (waveCount % 5 == 0 && waveCount <= 100)
I added waveCount <= 100 to replicate your code's behaviour when waveCount is larger than 100 i.e. not get into the if statement.
Alternatively, you can put all the values into a list:
var list = new List<int>();
for (int i = 1 ; i <= 20 ; i++) {
list.Add(i * 5);
}
And then check whether the list contains the number:
if (list.Contains(waveNumber))
The advantage of this is that if you decided to change how the game works and say that the shop menu can be opened at waves 9, 52, and 77, you just add the numbers to the list, without modifying the if statement. This provides a lot of flexibility.
if (waveCount % 5 == 0 && waveCount <= 50) {
//...code
}
If your “if” statement's body just contains shopPanel.SetActive(true); you can do that without even using “if” like that.
shopPanel.SetActive(waveCount % 5 == 0 && waveCount <= 50);
Give it a try
if (waveCount % 5 == 0 && waveCount <= 50)
Use the modulo-operator:
if(waveCount % 5 == 0 && waveCount <= 100) ...
The operator calculates the remainder of an integer-divison. In your case the statement should return zero indicating that your number divided by 5 has no remainder.
Just to generalize: in case the data you have doesn't match a pattern, you can put all the things to match against in a set, then test the set for membership:
var thingsToMatch = Set(2, 5, 8, 14, 23, 80, 274...);
if (someNumber in thingsToMatch) {...}
As long as you know the set isn't being recreated everytime the function is called, this has proven to be fairly fast. If your language doesn't automatically cache the set, you can make it a static variable of the function.
You can use the remainder operator for this:
if (waveCount % 5 == 0 && waveCount > 0 && waveCount <= 50)
{
//yield return new WaitForSeconds(shopWait);
shopPanel.SetActive(true);
}
You can test whether the remainder of the division by 5 is 0, which means that the number is divisible by 5.
if (waveCount % 5 == 0 && waveCount >= 5 && waveCount <= 50)
C# performs integer math on integer number types (int, long, uint, ...).
Example:
13 / 5 = 2
I.e. you never get a decimal fraction part. The complementary operation is the modulo operation. It gives you the remainder of this division:
13 % 5 = 3
I.e., 13 / 5 is 2 plus remainder 3. Together, division and modulo operation allow you to perform the reverse operation.
(5 * (13 / 5)) + (13 % 5) =
(5 * 2 ) + ( 3 ) = 13
If you have irregular figures, quite different approaches are to use a switch statement:
switch (waveCount) {
case 5:
case 10:
case 15:
case 20:
case 25:
case 30:
case 35:
case 40:
case 45:
case 50:
shopPanel.SetActive(true);
break;
}
or an array of allowed values:
private static readonly int[] AllowedValues =
new int[] { 5, 10, 15, 20, 25, 30, 35, 40, 45, 50 };
if(Array.IndexOf(AllowedValues, waveCount) >= 0) { ... }
What is the difference in both of the expressions ? Using brackets or not in this case. What is the difference ?
(!String.IsNullOrEmpty(model.SpouseCitizenType) || !String.IsNullOrEmpty(model.SpouseNomPrenom)) &&
String.IsNullOrEmpty(model.SpouseEGN);
!String.IsNullOrEmpty(model.SpouseCitizenType) || !String.IsNullOrEmpty(model.SpouseNomPrenom) &&
String.IsNullOrEmpty(model.SpouseEGN);
Operator AND && has a higher precendence than OR ||. So, if we denote conditions used here as 1, 2 and 3, first line is equvalent to
(1 || 2) && 3
and the second
1 || (2 && 3)
For the full list of operators sorted in order of precedence check out this MSDN page
I have an if statement as follows
if (1 <= value <= 20)
{
}
value is a double.
however I get an error which says that "Operator '<=' cannot be applied to operands of type 'bool' and 'double'"
Is there a way around this error?
C# doesn't allow you to do this.
Do like this:
if (1 <= value && value <= 20)
The problem is not the double, problem is your syntax is incorrect.
You:
if (1 <= value <= 20)
{
}
That is interpreted as
(1 <= value) <= 20
so first 1 will be compared with value and it will be determined if the former is "less than or equal" the latter. That gives a boolean. Then that boolean, True or False, is compared with <= to 20. But you cannot ask if True/False is less than or equal 20, in C#.
Problem : you can not check two expressions without Combining them.
Solution : i think you want to check whether value is in beteween 1 and 20
You can Use Logical AND && operator for checking this
Try This:
if (value >= 1 && value <= 20)
{
}
1 <= value evaluates out to be bool (false if value is less than 1 and true otherwise).
So it evaluates out to be (true <= 20) or (false <=20) and error states clearly that you cannot use operator <= to compare bool and double.
You need and (&&) operator to do comparison:
if (1 <= value && value <= 20)
{
}