Logical vs. Bitwise: vs. , || vs. |

I’m starting to incorporate bitwise operators into my code. Can anyone tell me why you’d bother to use the logical operators (, ||) instead of their bitwise counterparts (, |)?

One reason I would see would be for standardization, if you had a large project or library used for multiple projects, you wouldn’t want to confuse new programmers. That’d be the main thing for me, code readability by another party.

If you want to pack a lot of data into a small package, bitwise operators allow you to work on a binary level. The CharacterController Move function is a good example of this.

CollisionsFlags flags = characterController.Move(moveVector);

if((flags  CollisionFalgs.CollidedBelow) != 0)
  // We are on the ground

if((flags  CollisionFlags.CollidedAbove) != 0)
  // We have hit our head

If you were to store each of the collision flags as a boolean, even though it is only an on off type, it still gets stored in 8 bits, where as if you store it in a byte type, you can store 8 true or false bits of data using bitwise operators.

It was very important to save this amount of memory a while ago, now days memory comes in the Gigabytes, not Kilobytes, so it isn’t as important. It could be useful however for packing data for network sending, or saving to a file if you want to save space there.

I found this article quite good for explaining all the operators and how they actually work under the hood.

What I’m saying, is that I can’t find any good reason to use the symbols twice. I’m finding that one by itself does the trick. Why do the other versions exist?

you can’t confuse a compiler or another programmer with where leaves some interpretation. having both is standards and compatibility stuff. the ability to do | wouldn’t be there if we only had bitwise.

Do you have a resource that could tell me how they could differ?

I haven’t come across that yet. I don’t know how to Google it either, because searching “|” does not work. The pipe is thrown out, despite being in quotes.

http://msdn.microsoft.com/en-us/library/2a723cdk(VS.71).aspx

In other words, when x and y are complex evaluations, can be a lot faster than .

Because these operators are not the same:

int a = 3; // bits: 0011
int b = 4; // bits: 0100
if (a  b) // 0011  0100 = 0000!
{
   Debug.Log("We'll never get here. :(");
}
if (a  b)
{
   Debug.Log("We will get here!");
}

Additionally, it doesn’t make any sense whatsover to be using a bitwise operator when you are combining integers with, say, objects:

int c;
GameObject d;
// These expressions are meaningless!
if (c | d)
if (c  d)

The logical operators, on the other hand, do have a meaning when mixing types:

if (c || d) // Means: "c is not zero or d is not null"
if (c  d) // Means: "c is not zero AND d is not null"

Hence, there is a valid reason to have both sets of operators! QED :slight_smile:

spot on answers! and sorry jessy you are correct. i don’t think | is a defined logical in the c family (might be?). in java and | are both booleans and bitwise. so i guess i’ve just been combining them without needing to think about it.

That is the choose of convenience and performance.

Normally, I don’t use bit operation too much because of convenience, since the system have lot of resources (memory, IO, faster CPU etc)

However, when I working on some limited resource devices. ie. 8-bit controller, (say, running on 12Mhz, 256 byte ram and 2kB of program space) every code I wrote, I will consider for maximum performance and little footprint. Bit operation will help a lot for optimization. Of course, more planning is need, using bit operation is not easy, sometime maybe very confused :stuck_out_tongue: Well, I found that Cg programing on graphic card have almost the same situation. We need to take a special care when writing any code.

Thanks,
Antonio

<major thread derail!>

Also and || are robust when doing null-checks: You can write

if (myObject != null  myObject.IsVeryCool) {
    // some code only executed on cool objects
}

and it will never throw a NullReferenceException - because myObject.IsVeryCool is not even touched if myObject == null (which renders the first statement “false” so the whole expression can never be true).

Likewise, you could do

if (myObject == null || !myObject.IsVeryCool) {
    // some code only executed when no cool object is available ;-)
}

Now, when myObject is null, the first part is true - and so the whole statement always is true, so !myObject.IsVeryCool is not even touched.

I never use | or except as bit-operators, so I don’t know how this would behave when using those but I’m pretty sure you would get NullReferenceExceptions because for a bitwise operation both parts need to be evaluated (well, not really in those specific cases, so theoretically that could be “optimized away” but I guess it’s not due to the semantics of | and ).

Sunny regards,
Jashan

Considering that I have been writing if statements with this in mind (I put the easy evaluations first), this is very helpful!

Thanks everybody!

By translating the numbers to the binary system:

0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
etc.

Are you sure you’re correct about Zip+4 system? It would make much more sense to me if they just used standard binary numbers, in which case 1000 means 8 and 13 would be 1101 (and not 1110).

lol yeah I knew it was binary. Sadly I don’t have counting in it ingrained like base 10. Suppose I should dust off those cobwebs but it sure was too late for that last night. Yes the 7421 thing is how zip bar codes work. Always wondered where they came up with it. Binary would have made sense. Grab a piece of business reply mail (say a magazine subscription card). The left most bar is garbage. The next 4 are the first digit of the zip etc. 7400 = 0. Any garbage at the end identifies courtesy vs business reply (basically a check sum). Now tell me when you’ll ever use that useless knowledge! :slight_smile:

I’ve used bitwise operators a couple of times in the past, one to add up all the security for a user (1-CompanyA, 2-CompanyB, 4-CompanyC, 8-CompanyD), so if you had access to all 4, the security value owuld be 15. Then I could include the bits in a SQL operation and only get out what I needed using only one field. (Can’t remember exactly what I did, but it was handy at the time)