Today I needed a simple algorithm for checking if a number is a power of 2.
The algorithm needs to be:
ulong
After posting the question I thought of the following solution:
We need to check if exactly one of the binary digits is one. So we simply shift the number right one digit at a time, and return true
if it equals 1. If at any point we come by an odd number ((number & 1) == 1
), we know the result is false
. This proved (using a benchmark) slightly faster than the original method for (large) true values and much faster for false or small values.
private static bool IsPowerOfTwo(ulong number)
{
while (number != 0)
{
if (number == 1)
return true;
if ((number & 1) == 1)
// number is an odd number and not 1 - so it's not a power of two.
return false;
number = number >> 1;
}
return false;
}
Of course, Greg's solution is much better.
Find if the given number is a power of 2.
#include <math.h>
int main(void)
{
int n,logval,powval;
printf("Enter a number to find whether it is s power of 2\n");
scanf("%d",&n);
logval=log(n)/log(2);
powval=pow(2,logval);
if(powval==n)
printf("The number is a power of 2");
else
printf("The number is not a power of 2");
getch();
return 0;
}
This is another method to do it as well
package javacore;
import java.util.Scanner;
public class Main_exercise5 {
public static void main(String[] args) {
// Local Declaration
boolean ispoweroftwo = false;
int n;
Scanner input = new Scanner (System.in);
System.out.println("Enter a number");
n = input.nextInt();
ispoweroftwo = checkNumber(n);
System.out.println(ispoweroftwo);
}
public static boolean checkNumber(int n) {
// Function declaration
boolean ispoweroftwo= false;
// if not divisible by 2, means isnotpoweroftwo
if(n%2!=0){
ispoweroftwo=false;
return ispoweroftwo;
}
else {
for(int power=1; power>0; power=power<<1) {
if (power==n) {
return true;
}
else if (power>n) {
return false;
}
}
}
return ispoweroftwo;
}
}
A number is a power of 2 if it contains only 1 set bit. We can use this property and the generic function countSetBits
to find if a number is power of 2 or not.
This is a C++ program:
int countSetBits(int n)
{
int c = 0;
while(n)
{
c += 1;
n = n & (n-1);
}
return c;
}
bool isPowerOfTwo(int n)
{
return (countSetBits(n)==1);
}
int main()
{
int i, val[] = {0,1,2,3,4,5,15,16,22,32,38,64,70};
for(i=0; i<sizeof(val)/sizeof(val[0]); i++)
printf("Num:%d\tSet Bits:%d\t is power of two: %d\n",val[i], countSetBits(val[i]), isPowerOfTwo(val[i]));
return 0;
}
We dont need to check explicitly for 0 being a Power of 2, as it returns False for 0 as well.
OUTPUT
Num:0 Set Bits:0 is power of two: 0
Num:1 Set Bits:1 is power of two: 1
Num:2 Set Bits:1 is power of two: 1
Num:3 Set Bits:2 is power of two: 0
Num:4 Set Bits:1 is power of two: 1
Num:5 Set Bits:2 is power of two: 0
Num:15 Set Bits:4 is power of two: 0
Num:16 Set Bits:1 is power of two: 1
Num:22 Set Bits:3 is power of two: 0
Num:32 Set Bits:1 is power of two: 1
Num:38 Set Bits:3 is power of two: 0
Num:64 Set Bits:1 is power of two: 1
Num:70 Set Bits:3 is power of two: 0
return ((x != 0) && !(x & (x - 1)));
If x
is a power of two, its lone 1 bit is in position n
. This means x – 1
has a 0 in position n
. To see why, recall how a binary subtraction works. When subtracting 1 from x
, the borrow propagates all the way to position n
; bit n
becomes 0 and all lower bits become 1. Now, since x
has no 1 bits in common with x – 1
, x & (x – 1)
is 0, and !(x & (x – 1))
is true.
Mark gravell suggested this if you have .NET Core 3, System.Runtime.Intrinsics.X86.Popcnt.PopCount
public bool IsPowerOfTwo(uint i)
{
return Popcnt.PopCount(i) == 1
}
Single instruction, faster than (x != 0) && ((x & (x - 1)) == 0)
but less portable.