Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When are bitwise operations appropriate

I am aware of the basic premise of what bitwise operation are (although would appreciate a "for dummies" explanation); however I am unaware of when it is appropriate to use this technique.

My understanding is that older CPU architectures could perform bitwise operations faster then other operations and hence it was advantageous to know how to use them. Given this is no longer the case; is it still appropriate to perform them and if so, for what purpose and under what conditions? (I am specifically interested in the C# context but am happy to receive general answers)

like image 581
Maxim Gershkovich Avatar asked Apr 23 '11 03:04

Maxim Gershkovich


4 Answers

Bitwise operations are a great way to quickly check for a flag that may be set on a variable.

The following example highlights the benefits of using bitwise operations on a Flag enumeration as well as storing a bitstuffed field into a database. The bitstuffed field can then easily be checked to see if it contains a single value or subset of values from the Flag enumeration.

Example:

A User database table with a tinyint field called Permission. The field is populated using a value created with the enumeration which values are 2^n.

[Flags]
public enum Permission : byte
{
    None = 0,
    ManageUsers = 1 << 0,
    CreateOrders = 1 << 1,
    PurchaseEquipment = 1 << 2,
    CancelOrders = 1 << 3,
}

Apart from bitwise operations being used to specify values in the enumeration (done at compile time), you can use the enumeration to check if the Permission field in the database contains any subset of the possible values. From the database side you gain the ability to stuff values into a single field - eliminating the need to have a column for each permission and in the code side you gain an easy way to check for a value.

Example bitstuffing (Grant ManageUsers and CreateOrders):

Permission userPermissions = Permission.ManageUsers | Permission.CreateOrders;

Example permission check:

public bool HasPermissions(Permission userPermissions, Permission permissionsToCheckFor)
{
    return permissionsToCheckFor == Permission.None ? 
        false : 
        (userPermissions & permissionsToCheckFor) == permissionsToCheckFor;
}
like image 84
Adam Spicer Avatar answered Sep 18 '22 04:09

Adam Spicer


The issue is not so much that bitwise operations are faster than integer operation (although they usually are), it's that they are different operations for different purposes.

Conceptually bytes and shorts and ints are really tiny arrays of bits and bitwise operators are boolean array operators. In C# nowadays bitwise operators are mostly used for [Flags] enumerations and in calculations for GetHashCode but there are endless ways that arrays of bits can be used.

like image 28
Rick Sladkey Avatar answered Sep 21 '22 04:09

Rick Sladkey


You are correct that just because language gives you bitwise operation, you should not use them just because you can. I've seen people use bitwise operators when working with simple booleans and that's not what they are for.

Bitwise operators are useful when working with data structures where pieces of data are not aligned with byte boundary. Generally, this is done when bandwidth (or general memory footprint) is very important. I work on RTP video streaming software and bitwise operations are used both in reading/constructing RTP transmission packets as well as for reading video codec streams, which are often encoded using bits, not bytes.

like image 27
DXM Avatar answered Sep 21 '22 04:09

DXM


They can be really useful in embedded control situations when space is at a premium. For example, a single byte of data can represent 8 i/o bits, and masks can be used to retrieve the bits of interest from an i/o port (e.g. if PIN0 = 1, PIN1 = 2, PIN2 = 4, PIN3 = 8 and so on, then:

  • To get the value of PIN0, we can say PORT0 & PIN0 == 0.
  • To set PIN1 to 1, we can cay PORT0 |= PIN1.
  • To set PIN2 to 0, we can say PORT0 &= ~PIN2.

Away from embedded control, I rarely see this approached used these days. In the C# world it's much more common to see individual boolean fields for each value of interest, since the overhead is really not a big deal with modern hardware (though you may run into a case or two where bitwise operations are used to keep many such flags in a single variable).

There is also an interesting application in graphics. A neat trick for cursors or bounding boxes is to add them by XOR'ing the cursor shape with the image below. Performing the same operation again will result in the original image.

like image 33
afranz409 Avatar answered Sep 20 '22 04:09

afranz409