If an integer x
is a power of 2, only one bit is set, whereas x-1
has all bits set after that. For example: 4
is 100
and 3
is 011
as binary number, which satisfies the aforementioned condition. Zero is not a power of 2 and has to be checked explicitly.
boolean isPowerOfTwo(int x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
Usage for Left and Right Shift
Let’s suppose, we have three kind of permissions, READ, WRITE and EXECUTE. Each permission can range from 0 to 7. (Let’s assume 4 bit number system)
RESOURCE = READ WRITE EXECUTE (12 bit number)
RESOURCE = 0100 0110 0101 = 4 6 5 (12 bit number)
How can we get the (12 bit number) permissions, set on above (12 bit number)?
0100 0110 0101
0000 0000 0111 (&)
0000 0000 0101 = 5
So, this is how we can get the EXECUTE permissions of the RESOURCE. Now, what if we want to get READ permissions of the RESOURCE?
0100 0110 0101
0111 0000 0000 (&)
0100 0000 0000 = 1024
Right? You are probably assuming this? But, permissions are resulted in 1024. We want to get only READ permissions for the resource. Don’t worry, that’s why we had the shift operators. If we see, READ permissions are 8 bits behind the actual result, so if apply some shift operator, which will bring READ permissions to the very right of the result? What if we do:
0100 0000 0000 >> 8 => 0000 0000 0100 (Because it’s a positive number so replaced with 0’s, if you don’t care about sign, just use unsigned right shift operator)
We now actually have the READ permissions which is 4.
Now, for example, we are given READ, WRITE, EXECUTE permissions for a RESOURCE, what can we do to make permissions for this RESOURCE?
Let’s first take the example of binary permissions. (Still assuming 4 bit number system)
READ = 0001
WRITE = 0100
EXECUTE = 0110
If you are thinking that we will simply do:
READ | WRITE | EXECUTE
, you are somewhat right but not exactly. See, what will happen if we will perform READ | WRITE | EXECUTE
0001 | 0100 | 0110 => 0111
But permissions are actually being represented (in our example) as 0001 0100 0110
So, in order to do this, we know that READ is placed 8 bits behind, WRITE is placed 4 bits behind and PERMISSIONS is placed at the last. The number system being used for RESOURCE permissions is actually 12 bit (in our example). It can(will) be different in different systems.
(READ << 8) | (WRITE << 4) | (EXECUTE)
0000 0000 0001 << 8 (READ)
0001 0000 0000 (Left shift by 8 bits)
0000 0000 0100 << 4 (WRITE)
0000 0100 0000 (Left shift by 4 bits)
0000 0000 0001 (EXECUTE)
Now if we add the results of above shifting, it will be something like;
0001 0000 0000 (READ)
0000 0100 0000 (WRITE)
0000 0000 0001 (EXECUTE)
0001 0100 0001 (PERMISSIONS)