Or in IF statement not working properly - c#

I have this Or condition in an IF statement (in a foreach loop) in a Windows Form C# program:
if ((splittedFile.Count() != 3) || (splittedFile.Count() != 4))
continue;
and it always does continue, even if splittedFile.Count() is 3 or 4.
The thing is that if I remove the Or condition:
if ((splittedFile.Count() != 4))
continue;
it works properly!! Any ideas why?

This is the correct behavior, you need to use &&.
The reason is that the count is fixed number, let's say n. Now the condition reads:
n is not 3 or n is not 4.
Given n is 4, this means it is not 3, thus the test succeeds and vice versa.
A compiler can't detect this is trivially true, because between the two if statements, the Count() might change (for instance in a multithreading setting where the second thread would add/remove something to/from the collection). I agree however some analysis tools could be capable in some conditions to detect such trivial behavior. In general however such analysis can't be implemented because of Rice's theorem.
If you use &&, the expression reads:
n is not 3 and n is not 4.
Thus both conditions should be true. In other words only if n is less than three and greater than 4, the condition holds.

Try:
if ((splittedFile.Count() != 3) && (splittedFile.Count() != 4))
continue;
I know || sound logical because : if splittedFile.count is not 3 OR it is not 4 then continue; But because there are 2 NOT ! operators in the if expression an AND && is needed.

put a real number into your expression:
if( 3 != 3 || 3 != 4)
which is
if( false || true )
your expression will always be true, as splittedFile.Count() is always (not 3) or (not 4)
you want to && your results together, which looks like
(x != 3) || (x != 4)
or
!( x == 3 || x == 4)

Because one of your expressions will be always true. That's why true || something always returns true.
Let's analyze your splittedFile.Count() is 3, 4 and other than these values.
For 3, your expression will be false || true and this returns true.
For 4, your expression will be true || false and this returns true.
For other than 3 or 4, your expression will be true || true and this returns true.
Strongly suspect you are looking for && operator which provides logical-AND.

Related

Short circuit condition fail

I've a bit problem with a short circuit condition, what I need to do is check if an array have almost 2 indexes or a string is equal to a certain value, to recreate the problem here, suppose this:
string[] favItem = new string[] { "hello", "world", "test", "foo" };
string temp = "hello";
var itemToRemove = temp.Split(',');
foreach(var fav in favItem)
{
if(fav == "foo" || (itemToRemove.Length > 1 & fav == itemToRemove[0] || fav == itemToRemove[1]))
{
//do something
}
}
so essentially I need to compare fav with a default value, if this fail, I need to check if the itemToRemove array have almost 2 indexes, if yes I need to compare the fav value in iteration, with the two indexes of itemToRemove.
Now suppose that in itemToRemove there is only one index, I'm not able to exit from this:
(itemToRemove.Length > 1 & fav == itemToRemove[0] || fav == itemToRemove[1])
in particular with & I'm trying to exit from the condition if the indexes aren't two.
In the debug mode I can see the false value with the breakpoint, but I don't understand why the code fall to:
OutOfRangeException
with itemToRemove[1] when should be leave the condition.
What am I doing wrong?
Your code has two problems.
First, the short-circuiting boolean "and" operator is &&. & is the bitwise and operator, and does not short circuit.
Secondly, && has a higher precedence than ||, so you need to group the second || together like this (itemToRemove.Length > 1 && (fav == itemToRemove[0] || fav == itemToRemove[1])). The rule of thumb to remember precedence is that and is like multiplication 0 && 1 = 0, while or is like addition 0 || 1 = 1.
Short circuit is && not &.

Understanding simple ANSI C math expression in terms of C#

I've been presented what I think is an ANSI C statement but I don't understand what it is doing or if it is even valid.
x = (y == 4) * 12 + (y == 5) * 24;
Can anyone help me understand what this statement does in terms of C# (which I actually understand).
Thanks
Historically, C did not have a boolean type.* Comparison operators returned either 0 or 1, type int. Any int value (as well as other types) could be interpreted in boolean context, where 0 means false and any other value means true.
C# treats int and bool as completely separate types. The most direct C# equivalent is
x = (y == 4 ? 1 : 0) * 12 + (y == 5 ? 1 : 0) * 24;
Which can of course be improved greatly further.
* Typically, "ANSI C" is intended to refer to the original version of C, even though later versions of C have been adopted by ANSI too. Those later versions do add a boolean type, but the comparison operators still return int values. Similarly, integers in boolean contexts are still allowed as well. They do not change anything relevant to your question.
This is definitely wrong in C#. Both expressions, y==4 and y==5 are evaluated as a boolean. That being said, how can you define the multiplication between a boolean and an integer? This expression is not correct in C#.
I would say that you could try the following:
x = (y == 4 ? 1 : 0) * 12 + (y == 5 ? 1 : 0) * 24;
In the above expression we use the ternary operator, whose logic is quite simple it the expression evaluates to true then return the result after the question mark. Otherwise it returns the value after the :. So if y is equals to 4, then (y == 4 ? 1 : 0) evaluates to 1. Otherwise, it returns 0.
The above solution is based on that hvd mentioned below in his comment, that == returns either 0 or 1 in C.

C# Conditioning Difference In OR Operator

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

While loop not properly checking all conditions?

So the assignment is as follows: you can enter all sorts of numbers but when you enter 0 two times in a row it needs to stop. The first time you enter a number your not allowed to enter 0.
This is the code I have setup:
class MainClass
{
public static void Main (string[] args)
{
int givenNumber, prevNumber;
Console.WriteLine ("Enter a number: ");
int.TryParse (Console.ReadLine (), out givenNumber);
// I've set the prevNumber to givenNumber because the variable has to be initialized
// before I can use it in the condition below. I thought setting it to the giveNumber
// wouldn't harm. Note that the first time your not allowed to enter 0
prevNumber = givenNumber;
while (givenNumber != 0 && prevNumber != 0) {
prevNumber = givenNumber; //Here is where they both are 0 at a given moment, but only after the condition.
Console.WriteLine ("Enter a number: ");
int.TryParse (Console.ReadLine (), out givenNumber);
}
Console.WriteLine ("Tada");
}
}
The problem is that it already stops when you've only entered one 0. For example if I'd first enter a 7 to start with, and my next number would be 0. When I debug it it says that my givenNumber is 0 and prevNumber is 7, when it goes back to the while condition it stops and finishes. When the program finishes the debug clearly says prevNumber = 7 and givenNumber = 0. I am using the conditional AND correct am I not?
Any clue? I'm not allowed to use arrays for this matter.
Thanks in advance
Ooh, right, you've got the logic wrong. It should be this:
while ((givenNumber != 0) || (prevNumber != 0)) {
Look up DeMorgan's laws to see why...
Your problem is with your conditional statement.
Right now you're checking whether both the givenNumber and the PrevNumber DO NOT equal 0.
So, if neither of them equals 0 then the statement will evaluate to TRUE. However, if either one of the numbers is 0 then the statement will evaluate to FALSE, since (TRUE) && (FALSE) evaluates to FALSE.
There are two ways to fix this: You can either use || (the "OR" operator) with the two "!=" statements, or you can negate the whole thing and use regular equality rather than "!=" as such: !(givenNumber == 0 && prevNumber == 0)
while (givenNumber != 0 && prevNumber != 0)
For first read value from console - number 7
givenNumer will be 7
prevNumber will be 7 too (because of assignment prevNumber = givenNumber;)
Thus while (7 != 0 && 7 != 0) will pass
Second read from Console - number 0
Thus while (0 != 0 && 7 != 0) will not pass because 0 != 0 is FALSE and while loop ends if condition is result is FALSE

More efficient boolean algebra for conditions comparing wild cards

In casino slot games you often have a Wild game piece. What would be a good way of including this mechanic into comparing with 2 other pieces? e.g. given 3 game pieces [Cherry][Cherry][Joker] would be a match.
The code I'm using right now seems really overweight, is there anything that can be done (think bitwise operators?) to make it easier to work with?
if ((box1.BoxRank == box2.BoxRank ||
box1.BoxRank == BoxGameObject.Ranks.Joker ||
box2.BoxRank == BoxGameObject.Ranks.Joker) &&
(box1.BoxRank == box3.BoxRank ||
box1.BoxRank == BoxGameObject.Ranks.Joker ||
box3.BoxRank == BoxGameObject.Ranks.Joker) &&
(box2.BoxRank == box3.BoxRank ||
box2.BoxRank == BoxGameObject.Ranks.Joker ||
box3.BoxRank == BoxGameObject.Ranks.Joker))
{
// has 3 of a kind, or 1 joker and 2 of a kind, or 2 jokers and 1 other
return true;
}
This is easier if you think of the operation in terms of the set of the value of all of the boxes. Just remove all of the jokers from that set and then verify that all of the values are identical:
var allRanks = new[]{box1.BoxRank, box2.BoxRank, box3.BoxRank};
var threeOfAKind = allRanks.Where(rank => rank != BoxGameObject.Ranks.Joker)
.Distinct()
.Count() < 2;
First just remove all of the jokers. If, after doing that, there are two or more distinct values then we do not have a three of a kind.
Yes, represent the Joker as an int with all binary 1's, like 7, 15 or 31.
Represent the cherry and others with an int with only singe binary 1 like 1,2,4,8 smaller than the Joker. Leave zero unused.
Then, using bitwise AND your condition is equivalent to:
(box1.BoxRank & box2.BoxRank & box3.BoxRank) > 0
Note that 3 Jokers will satisfy the condition too.

Categories