Skip to main content
gamedev.net
🔒 Locked

Bitwise and logical

Started by BrasiLokau Jul 28, 2007 at 11:19 AM 12 replies 4.1k views
Original Post
BrasiLokau
BrasiLokau
Can someone explain to me what is the different between bitwise and logical interpretations of AND OR XOR?????????? Thanks a lot
blog: www.brasilokau.com/games/blog
Spoonbender
Spoonbender
It's all in the name. [smile]

A logical AND (the && operator)is one that goes "X is true if Y AND Z are true".
Logical OR (the || operator)is similar: "X is true if either Y OR Z are true".
That's plain everyday logic. And it works on logic values (bools, which can be true or false)

Bitwise (the & and | operators), as the name implies, works on individual bits.
What it does is really make the same logical test on each individual bit.
An int is 32 bits wide. So if you bitwise OR two ints together, the result is an int where the first bit is set if the first bit if either input 1 OR input 2 was set. The second bit is set if the second bit of either one of the inputs was set. And so on.
novaleaf software
novaleaf software
spoonbender is totally correct,

and to elaborate a little,

generally speaking (standard .NET programming), you will only find the bitwise operators ( & and | ) useful when you are dealing with [FLAGS] enumerations.

I have not used bitwise operator for anything else in my career so far, and I'm pretty experienced with 6 years so far.

If anyone can think of useful reasons for bitwise on something else, let me know. The only potential uses i can think of right now, might be if you are creating an encryption algorithm, or perhaps some other arcane performance reason.

JWalsh
JWalsh
The above is not entirely true. What was described was the difference between the logical, aka bitwise (| & ~) operators and the conditional (|| &&) operators when working with integral types. (int, uint, short, ulong, etc...)

Unlike C++, C# treats them a bit differently when working with boolean types.

There was a complete discussion about this earlier in the week. For a full, complete description of these difference, check This Thread. Pay Special attention to my final post at the end.

I encourage people who are answering questions to make sure they are speaking from their knowledge of C#, and not their knowledge of C++. C# is a different language, and has some nuances that you need to watch out for.

Cheers!
Spoonbender
Spoonbender
Oo, didn't know that | and & were defined for bools.
(However, since the question was simply what the difference between bitwise and logical versions of AND and OR were, I still think the above was correct, even if it didn't tell the full story)
(A bitwise operation is one that works on each bit in the input and output, a logical one is one that works on truth values, or booleans. It takes two booleans, and returns a boolean, without fiddling with individual bits. C# then has some rules I wasn't aware of, about how the operands are evaluated, but the difference between a logical and bitwise operation is still the same)

Anyway, as far as I can tell, || and && aren't defined at all for integral types. At least, I can't get anything to compile when using them. [wink]
Am I missing something here?
savagemonitor
savagemonitor
IIRC the statements on both sides of the && and || operators must evaluate to a boolean. I believe that this is due to the fact that && and || will do short circuit evaluations while & and | will not.
JWalsh
JWalsh
Quote:
Original post by Spoonbender
Oo, didn't know that | and & were defined for bools.
(However, since the question was simply what the difference between bitwise and logical versions of AND and OR were, I still think the above was correct, even if it didn't tell the full story)
(A bitwise operation is one that works on each bit in the input and output, a logical one is one that works on truth values, or booleans. It takes two booleans, and returns a boolean, without fiddling with individual bits. C# then has some rules I wasn't aware of, about how the operands are evaluated, but the difference between a logical and bitwise operation is still the same)

Anyway, as far as I can tell, || and && aren't defined at all for integral types. At least, I can't get anything to compile when using them. [wink]
Am I missing something here?


| and & are indeed defined for bools.

And no, your answer was not correct. The second part of your answer clearly states that | and & (the bitwise operators) perform a bitwise comparison. However, when working with boolean values, this is not true. Which is why they are not called "bitwise operators" in C#. They are simply the logical AND, OR and XOR. How they perform their comparisons differs between integral and boolean types, but in either event its a logical comparison.

Some people continue to call them the bitwise AND and OR because it's a carryover from C and C++. However, this is a gross mistake as it implies a universal behavior which is now type specific.

Furthermore, your first paragraph is also incorrect as && and || are not the logical AND and OR in C#, they are the "Conditional" AND and OR. This is an important distinction as it means that evaluation of the second term is conditional upon the failure case of the first term. To a C++ programmer this is just the way it's always been, but to a C# programmer this is an important distinction as it highlighs a key difference between logical OR | and conditional OR ||.

And finally, you are correct; && and || are not defined for anything other than boolean types. This too is unique to C#. C++ would allow (int && int) as it implicitly casts int to bool. C# does not.

So in summary, Conditional || and && are only defined for boolean types, and &, ^, and | can be used on BOTH integral and Boolean types, and the behavior is different depending upon which data type you're working with.

Cheers!
Daerax
Daerax
Where would someone use the logical operators "|, &,.." and not the Conditional logical operators "||,&&,..."?

This page seems to imply that one would only use | when the need for custom operators and operator overloading arises.
stonemetal
stonemetal
since || and && shortcircuit you use them when you just need the boolean value. You use & | when the full results need to be calculated.
Daerax
Daerax
Quote:
Original post by stonemetal
since || and && shortcircuit you use them when you just need the boolean value. You use & | when the full results need to be calculated.


Full results? Can you clarify when this would be?

What test cases I have tryed over the boolean type and the documentation seem to suggest that the results of expressions with | and || will be the same. I have tried !(A && B), !A | !B to !A || B, !A | B and they both evaluate the same.
Spoonbender
Spoonbender
Quote:
Original post by JWalsh
Furthermore, your first paragraph is also incorrect as && and || are not the logical AND and OR in C#, they are the "Conditional" AND and OR. This is an important distinction as it means that evaluation of the second term is conditional upon the failure case of the first term.

As far as I'm aware (from a general computer science background, not specifically C#), AND and OR are logic operations, they work on logic values. Generally speaking, it doesn't say in the rulebook which argument should be evaluated first, or whether short-circuiting is allowed. That doesn't make them stop being logic operations.
A logical OR is simply one that takes two logic values, and yields true if one of the inputs are true.
And that is what both C#'s logical and conditional operators do.
So both are (in the OP's words) logical interpretations of AND and OR.

Of course you're right, there are some important differences in how they're actually evaluated. (Which I wasn't previously aware of), but my point is that the logical operations they perform are the same. Even if some of the side effects are different.
(I think this is a point worth making, because otherwise, people will try out different combinations of logic values, trying to get the two operators to behave differently, like Daerax did in the above post)

But yeah, in C# terminology, only | and & (as defined on bools) are logical operators, while && and || are conditional operators. Sorry for the confusion. [grin]

Quote:

And finally, you are correct; && and || are not defined for anything other than boolean types. This too is unique to C#. C++ would allow (int && int) as it implicitly casts int to bool. C# does not.

Yay, I caught an error too [lol]

Quote:
What test cases I have tryed over the boolean type and the documentation seem to suggest that the results of expressions with | and || will be the same. I have tried !(A && B), !A | !B to !A || B, !A | B and they both evaluate the same.

As I tried to argue in the beginning of my post (hope it didn't cause too much confusion), the logical operations performed are indeed exactly the same.
The difference is in the side effects.
Consider this slightly contrived example:
if (TryMoveLeft() && TryMoveUp() ){<do stuff here>}

Let's say the two functions try to move the character one tile left or up, and if it fails, they return false, otherwise they return true.
Now the player is trying to move diagonally, so we reach the if statement above (because we're trying to both move left and up)
With the && operator, TryMoveUp() will never be executed if TryMoveLeft() fails. If there's a wall to the left of me, I'll just stand still when trying to move diagonally up and left.

If you were to use the & (logical) operator instead of && (conditional), then both would always be evaluated. The character would try to move up regardless of whether the left move succeeded.
So if I can't move left, but try to move diagonally, my character will still move straight up.

However, you'll reach the line in the same cases, regardless of which operator you use.
The side effects (the movement of the character) turn out differently, but the logical result of the AND or OR is the same.

Make sense?

Another, more dramatic example would be this one:

if (true | InfiniteLoop()){

}

With the | operator, we're screwed. We'll enter an infinite loop, and get stuck forever.
If we'd used || instead, InfiniteLoop() wouldn't get called, because the first operand tells us all we need to know. Whatever InfiniteLoop returns, it can't change the result of the logical (sorry, conditional) operation.
So with ||, we wouldn't get stuck in an infinite loop.
Daerax
Daerax
Quote:
Original post by Spoonbender
As I tried to argue in the beginning of my post (hope it didn't cause too much confusion), the logical operations performed are indeed exactly the same.
The difference is in the side effects.
Consider this slightly contrived example:
if (TryMoveLeft() && TryMoveUp() ){<do stuff here>}

Let's say the two functions try to move the character one tile left or up, and if it fails, they return false, otherwise they return true.
Now the player is trying to move diagonally, so we reach the if statement above (because we're trying to both move left and up)
With the && operator, TryMoveUp() will never be executed if TryMoveLeft() fails. If there's a wall to the left of me, I'll just stand still when trying to move diagonally up and left.

If you were to use the & (logical) operator instead of && (conditional), then both would always be evaluated. The character would try to move up regardless of whether the left move succeeded.
So if I can't move left, but try to move diagonally, my character will still move straight up.

However, you'll reach the line in the same cases, regardless of which operator you use.
The side effects (the movement of the character) turn out differently, but the logical result of the AND or OR is the same.

Make sense?

Suppose TryMoveLeft() returned False while TryMoveUp() returned true then && would be False and if(){} would not be entered since the conditional operator wont even bother Checking TryMoveUp(). Assuming TryMove() only does a check but does not actually act on the state of the game then it should still return False since False & True is False. so there would not be movement and if(){} would still not be called. Same Result.

As you note the second case is where TryMove() tries to move and does so if it can, returning its outcome. TL() && TU() would do nothing. TL() & TU() would move up ( if(){} wont be entered either) even though the move Northwest was the input. Unexpected behaviour. A better movement algorithm would be called for. But I see your point. Thanks. The operators act on their input in the sameway but you use the conditional especially when you wish to direct the behaviour based on the inputs of your logic check. The normal boolean does not care and simply evaluates.

Quote:
Another, more dramatic example would be this one:

if (true | InfiniteLoop()){

}

With the | operator, we're screwed. We'll enter an infinite loop, and get stuck forever.
If we'd used || instead, InfiniteLoop() wouldn't get called, because the first operand tells us all we need to know. Whatever InfiniteLoop returns, it can't change the result of the logical (sorry, conditional) operation.
So with ||, we wouldn't get stuck in an infinite loop.

That one is different I see. (InfiniteLoop() || True) would be just as bad though.

[Edited by - Daerax on July 30, 2007 7:45:23 AM]
Spoonbender
Spoonbender
Quote:
Original post by DaeraxA better movement algorithm would be called for

Yes [grin]

But it was the best example I could think of.

Quote:
Thanks. The operators act on their input in the sameway but you use the conditional especially when you wish to direct the behaviour based on the inputs of your logic check

Or when it isn't essential (or downright dangerous) that the second operand gets called.

A less contrived, and much more common example of that is:
if (foo != null && foo.bar()){  // Do with foo}

foo might be null, so we can't just call foo.bar() without first checking for null.
The conditional operator does the job correctly here. (bar() is only called if foo is not null, so this code is safe, and won't suddenly give us null references)
The logical operator would call bar() even if foo was null. That'd be bad. [lol]

(Reason I didn't use it before was that you asked for an example of when you'd use the logical instead of conditional operators, and this shows when you'd use the conditionals)

Quote:
That one is different I see. (InfiniteLoop() || True) would be just as bad though.

Yes.
DevFred
DevFred
Quote:
Original post by Daerax
Where would someone use the logical operators "|, &,.." and not the Conditional logical operators "||,&&,..."?

Besides the mentioned side effects, it can also have performance reasons.

If a and b are quite complex function calls, then (a && b) is faster, because you may not need to call b if a is evaluated to false.

If a and b are just boolean variables, then (a & b) is faster, because the compiled code ends up having less conditional jumps (which confuses the pipeline, a simple AND is always better performance wise).

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.