When Should I Use a Bitwise Operator

Real world use cases of bitwise operators

  • Bit fields (flags)
    They're the most efficient way of representing something whose state is defined by several "yes or no" properties. ACLs are a good example; if you have let's say 4 discrete permissions (read, write, execute, change policy), it's better to store this in 1 byte rather than waste 4. These can be mapped to enumeration types in many languages for added convenience.

  • Communication over ports/sockets
    Always involves checksums, parity, stop bits, flow control algorithms, and so on, which usually depend on the logic values of individual bytes as opposed to numeric values, since the medium may only be capable of transmitting one bit at a time.

  • Compression, Encryption
    Both of these are heavily dependent on bitwise algorithms. Look at the deflate algorithm for an example - everything is in bits, not bytes.

  • Finite State Machines
    I'm speaking primarily of the kind embedded in some piece of hardware, although they can be found in software too. These are combinatorial in nature - they might literally be getting "compiled" down to a bunch of logic gates, so they have to be expressed as AND, OR, NOT, etc.

  • Graphics
    There's hardly enough space here to get into every area where these operators are used in graphics programming. XOR (or ^) is particularly interesting here because applying the same input a second time will undo the first. Older GUIs used to rely on this for selection highlighting and other overlays, in order to eliminate the need for costly redraws. They're still useful in slow graphics protocols (i.e. remote desktop).

Those were just the first few examples I came up with - this is hardly an exhaustive list.

When should I use a bitwise operator?

Bitwise | and & and logical || and && are totally different.

Bitwise operators perform operations on the bits of two numbers and return the result. That means it's not a yes or no thing. If they're being used in conditional statements, they're often used as part of logical comparisons. For example:

if ($x & 2 == 2) {
// The 2^1 bit is set in the number $x
}

Logical operators compare two (or more) conditions/expressions and return true or false. You use them most commonly in conditional statements, like if and while. For example:

if ($either_this || $or_this) {
// Either expression was true
}

When to use Bitwise Operators during webdevelopment?

My main use for bitwise operators could be relevant anywhere - representing a set of flags. For instance, you might have an integer in the database representing a set of security permissions for a user, and in your web app you would have to check those before continuing.

Those tend to only require & and | - e.g.

if ((permissions & Permission.CreateUser) != 0)
{
...
}

or

Permission requiredPermission = Permission.CreateUser
| Permission.ChangePassword;

Bit shifting operators are less useful in "business" applications in my experience.

When to use the bitwise and operator (&)?

As the comments mentioned, num&1 is a bitwise AND between num and 1.

Since 1 in binary is ...000000001, the AND will result True iff the least significant bit of num is 1, in other words, if it is odd (here some explanation of binary)

When are bitwise operations appropriate

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;
}

Why would we use bitwise operators between 2 numbers?

These kinds of operators are used for lots of things, but these days in higher level languages they are most commonly used with flags. It's a holdover from lower level languages like C, in which memory allocation and deallocation is not always trivial, and which was developed at a time where hardware resources were scarce.

Let's say there are 3 possible flags for some operation, and they can be provided in any given combination. A quick, easy, and efficient way to supply a flag is to assign each flag to a bit in an integer.

public static final int FLAG_1 = 1;       // 00000001
public static final int FLAG_2 = 1 << 1; // 00000010
public static final int FLAG_3 = 1 << 2; // 00000100

Then to send multiple flags, I can use the bitwise or "|" operator.

someFunc(FLAG_1 | FLAG_3).

To read the flags that are passed, I can use the bitwise & operator.

public void someFunc(int flags) {
if ((flags & FLAG_1) == FLAG_1 /*Or (flags & FLAG_1) != 0 */) {
// Passed in flag 1.
}
}

There are other ways that this can be done, but this is very efficient, easy to read, and results in zero object allocations on the heap. If you think of other ways you'd accomplish this in Java, let's say with an array or collection of enums/ints, or with each flag being a separate method parameter, it's clear why this pattern is used instead.

Is It Worth Using Bitwise Operators In Methods?

You are asking the wrong question entirely. The question you should be asking is "should I keep my code simple and readable, or use tricks that I believe will improve its performance, even though I haven't measured its performance." The answer should be obvious.

Bitwise operators have their place, especially when you're dealing with binary file formats that need to pack a lot of data into small space. And it's absolutely critical to know how to mask out the high bits of a byte so that you don't accidentally sign-extend (print out these two variables to see what I mean):

byte b = (byte)0xDC;
int i = b & 0xFF;

But don't go looking for places to use these operators, especially to replace such simple tasks as dividing by 2.

Can I use bitwise operators instead of logical ones?

One possible answer is: optimization. For example:

if ((age < 0) | (age > 100))

Let assume that age = -5, no need to evaluate (age > 100) since the first condition is satisfied (-5<0). However, the previous code will do evaluate the (age > 100) expression which is not necessary.

With:

if ((age < 0) || (age > 100))

Only the first part will be evaluated.

Note: As @Lundin mentioned in the comments, sometimes | is faster than || due to the accuracy of branching for the second option (and the problem of mis-prediction). So in cases where the other expression is so inexpensive, the | option may be faster. So the only way to know in those cases is to benchmark the code on the target platform.


The most important answer is to avoid undefined behaviors and errors:

You may imagine this code:

int* int_ptr = nullptr;
if ((int_ptr != nullptr) & (*int_ptr == 5))

This code contains undefined behaviour. However, if you replace the & with &&, No undefined behaviour exists anymore.

Why do certain situations require the use of 'bitwise' operators instead of 'logical' / 'equality' operators?

The bitwise AND is somewhat special. == checks for equality but the bitwise AND operator allows you to work with the individual bits of a number.

Imagine your event was defined as a list of keys:

event = ['a', 'shift', 'ctrl']

You can then check to see if a particular modifier is a part of the event pretty easily:

if 'shift' in event:
# ...

The bitwise AND is sort of like an in statement. You can define your event as a binary number like this:

event = 00010010

Now, when you perform the bitwise AND, you can easily check to see if a certain modifier has been applied to the event, as modifiers are also represented as binary numbers:

  00010001  # event (18)
& 00010000 # shift key (8)
----------
00010000 # you get a non-zero answer, so the shift key is in the event
----------

00010001 # event (18)
& 00001000 # "z" key (4)
----------
00000000 # you get zero because the "z" key wasn't a part of the event
----------

You can construct an event like this using the bitwise OR:

  00000001  # shift key (1)
| 10100000 # "a" key (160)
----------
10100001 # resulting event (161)
----------

Wikipedia sums up bitwise operations pretty well:

A bitwise operation operates on one or more bit patterns or binary numerals at the level of their individual bits. It is a fast, primitive action directly supported by the processor, and is used to manipulate values for comparisons and calculations. On simple low-cost processors, typically, bitwise operations are substantially faster than division, several times faster than multiplication, and sometimes significantly faster than addition. While modern processors usually perform addition and multiplication just as fast as bitwise operations due to their longer instruction pipelines and other architectural design choices, bitwise operations do commonly use less power/performance because of the reduced use of resources.

Basically, bitwise operators allow you to work with information stored in the bits of an integer efficiently.



Related Topics



Leave a reply



Submit