c# More elegant way of finding if number is in range - c#

At the moment in one of my projects that I am working on, I need to check if a value falls between a number divisible by 12 and a number divisible by 12 + 5.
if (Number >= 0 && Number <= 5) {
value = 0;
} else if (Number >= 12 && Number <= 17) {
value = 12;
} else if (Number >= 24 && Number <= 29) {
value = 24;
}
// etc...
The code above works perfectly but I feel that it could be cut down. Does anyone have an alternative way of how to achieve what I am going for but more elegantly?

Use the % operator. (See http://msdn.microsoft.com/en-us/library/0w4e0fzs.aspx)
This should work as long as Number is positive; if it's not you'll have to look into how % works for negative numbers:
if (Number % 12 <= 5) {
value = 12*(int)(Number/12);
}

Related

Determinate if a number is power of 2 but i have a problem [duplicate]

Today I needed a simple algorithm for checking if a number is a power of 2.
The algorithm needs to be:
Simple
Correct for any ulong value.
I came up with this simple algorithm:
private bool IsPowerOfTwo(ulong number)
{
if (number == 0)
return false;
for (ulong power = 1; power > 0; power = power << 1)
{
// This for loop used shifting for powers of 2, meaning
// that the value will become 0 after the last shift
// (from binary 1000...0000 to 0000...0000) then, the 'for'
// loop will break out.
if (power == number)
return true;
if (power > number)
return false;
}
return false;
}
But then I thought: How about checking if log2 x is an exactly a round number? When I checked for 2^63+1, Math.Log() returned exactly 63 because of rounding. So I checked if 2 to the power 63 is equal to the original number and it is, because the calculation is done in doubles and not in exact numbers.
private bool IsPowerOfTwo_2(ulong number)
{
double log = Math.Log(number, 2);
double pow = Math.Pow(2, Math.Round(log));
return pow == number;
}
This returned true for the given wrong value: 9223372036854775809.
Is there a better algorithm?
There's a simple trick for this problem:
bool IsPowerOfTwo(ulong x)
{
return (x & (x - 1)) == 0;
}
Note, this function will report true for 0, which is not a power of 2. If you want to exclude that, here's how:
bool IsPowerOfTwo(ulong x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
Explanation
First and foremost the bitwise binary & operator from MSDN definition:
Binary & operators are predefined for the integral types and bool. For
integral types, & computes the logical bitwise AND of its operands.
For bool operands, & computes the logical AND of its operands; that
is, the result is true if and only if both its operands are true.
Now let's take a look at how this all plays out:
The function returns boolean (true / false) and accepts one incoming parameter of type unsigned long (x, in this case). Let us for the sake of simplicity assume that someone has passed the value 4 and called the function like so:
bool b = IsPowerOfTwo(4)
Now we replace each occurrence of x with 4:
return (4 != 0) && ((4 & (4-1)) == 0);
Well we already know that 4 != 0 evals to true, so far so good. But what about:
((4 & (4-1)) == 0)
This translates to this of course:
((4 & 3) == 0)
But what exactly is 4&3?
The binary representation of 4 is 100 and the binary representation of 3 is 011 (remember the & takes the binary representation of these numbers). So we have:
100 = 4
011 = 3
Imagine these values being stacked up much like elementary addition. The & operator says that if both values are equal to 1 then the result is 1, otherwise it is 0. So 1 & 1 = 1, 1 & 0 = 0, 0 & 0 = 0, and 0 & 1 = 0. So we do the math:
100
011
----
000
The result is simply 0. So we go back and look at what our return statement now translates to:
return (4 != 0) && ((4 & 3) == 0);
Which translates now to:
return true && (0 == 0);
return true && true;
We all know that true && true is simply true, and this shows that for our example, 4 is a power of 2.
Some sites that document and explain this and other bit twiddling hacks are:
http://graphics.stanford.edu/~seander/bithacks.html
(http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2)
http://bits.stephan-brumme.com/
(http://bits.stephan-brumme.com/isPowerOfTwo.html)
And the grandaddy of them, the book "Hacker's Delight" by Henry Warren, Jr.:
http://www.hackersdelight.org/
As Sean Anderson's page explains, the expression ((x & (x - 1)) == 0) incorrectly indicates that 0 is a power of 2. He suggests to use:
(!(x & (x - 1)) && x)
to correct that problem.
return (i & -i) == i
The following addendum to the accepted answer may be useful for some people:
A power of two, when expressed in binary, will always look like 1 followed by n zeroes where n is greater than or equal to 0. Ex:
Decimal Binary
1 1 (1 followed by 0 zero)
2 10 (1 followed by 1 zero)
4 100 (1 followed by 2 zeroes)
8 1000 (1 followed by 3 zeroes)
. .
. .
. .
and so on.
When we subtract 1 from these kind of numbers, they become 0 followed by n ones and again n is same as above. Ex:
Decimal Binary
1 - 1 = 0 0 (0 followed by 0 one)
2 - 1 = 1 01 (0 followed by 1 one)
4 - 1 = 3 011 (0 followed by 2 ones)
8 - 1 = 7 0111 (0 followed by 3 ones)
. .
. .
. .
and so on.
Coming to the crux
What happens when we do a bitwise AND of a number x, which is a
power of 2, and x - 1?
The one of x gets aligned with the zero of x - 1 and all the zeroes of x get aligned with ones of x - 1, causing the bitwise AND to result in 0. And that is how we have the single line answer mentioned above being right.
Further adding to the beauty of accepted answer above -
So, we have a property at our disposal now:
When we subtract 1 from any number, then in the binary representation the rightmost 1 will become 0 and all the zeroes to the left of that rightmost 1 will now become 1.
One awesome use of this property is in finding out - How many 1s are present in the binary representation of a given number? The short and sweet code to do that for a given integer x is:
byte count = 0;
for ( ; x != 0; x &= (x - 1)) count++;
Console.Write("Total ones in the binary representation of x = {0}", count);
Another aspect of numbers that can be proved from the concept explained above is "Can every positive number be represented as the sum of powers of 2?".
Yes, every positive number can be represented as the sum of powers of 2. For any number, take its binary representation. Ex: Take number 117.
The binary representation of 117 is 1110101
Because 1110101 = 1000000 + 100000 + 10000 + 0000 + 100 + 00 + 1
we have 117 = 64 + 32 + 16 + 0 + 4 + 0 + 1
bool IsPowerOfTwo(ulong x)
{
return x > 0 && (x & (x - 1)) == 0;
}
Here's a simple C++ solution:
bool IsPowerOfTwo( unsigned int i )
{
return std::bitset<32>(i).count() == 1;
}
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.
bool IsPowerOfTwo(int n)
{
if (n > 1)
{
while (n%2 == 0)
{
n >>= 1;
}
}
return n == 1;
}
And here's a general algorithm for finding out if a number is a power of another number.
bool IsPowerOf(int n,int b)
{
if (n > 1)
{
while (n % b == 0)
{
n /= b;
}
}
return n == 1;
}
bool isPow2 = ((x & ~(x-1))==x)? !!x : 0;
bool isPowerOfTwo(int x_)
{
register int bitpos, bitpos2;
asm ("bsrl %1,%0": "+r" (bitpos):"rm" (x_));
asm ("bsfl %1,%0": "+r" (bitpos2):"rm" (x_));
return bitpos > 0 && bitpos == bitpos2;
}
int isPowerOfTwo(unsigned int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
This is really fast. It takes about 6 minutes and 43 seconds to check all 2^32 integers.
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.
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;
}
for any power of 2, the following also holds.
n&(-n)==n
NOTE: fails for n=0 , so need to check for it
Reason why this works is:
-n is the 2s complement of n. -n will have every bit to the left of rightmost set bit of n flipped compared to n. For powers of 2 there is only one set bit.
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
Here is another method I devised, in this case using | instead of & :
bool is_power_of_2(ulong x) {
if(x == (1 << (sizeof(ulong)*8 -1) ) return true;
return (x > 0) && (x<<1 == (x|(x-1)) +1));
}
It's very easy in .Net 6 now.
using System.Numerics;
bool isPow2 = BitOperations.IsPow2(64); // sets true
Here is the documentation.
Example
0000 0001 Yes
0001 0001 No
Algorithm
Using a bit mask, divide NUM the variable in binary
IF R > 0 AND L > 0: Return FALSE
Otherwise, NUM becomes the one that is non-zero
IF NUM = 1: Return TRUE
Otherwise, go to Step 1
Complexity
Time ~ O(log(d)) where d is number of binary digits
There is a one liner in .NET 6
// IsPow2 evaluates whether the specified Int32 value is a power of two.
Console.WriteLine(BitOperations.IsPow2(128)); // True
Improving the answer of #user134548, without bits arithmetic:
public static bool IsPowerOfTwo(ulong n)
{
if (n % 2 != 0) return false; // is odd (can't be power of 2)
double exp = Math.Log(n, 2);
if (exp != Math.Floor(exp)) return false; // if exp is not integer, n can't be power
return Math.Pow(2, exp) == n;
}
This works fine for:
IsPowerOfTwo(9223372036854775809)
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.
in this approach , you can check if there is only 1 set bit in the integer and the integer is > 0 (c++).
bool is_pow_of_2(int n){
int count = 0;
for(int i = 0; i < 32; i++){
count += (n>>i & 1);
}
return count == 1 && n > 0;
}
In C, I tested the i && !(i & (i - 1) trick and compared it with __builtin_popcount(i), using gcc on Linux, with the -mpopcnt flag to be sure to use the CPU's POPCNT instruction. My test program counted the # of integers between 0 and 2^31 that were a power of two.
At first I thought that i && !(i & (i - 1) was 10% faster, even though I verified that POPCNT was used in the disassembly where I used__builtin_popcount.
However, I realized that I had included an if statement, and branch prediction was probably doing better on the bit twiddling version. I removed the if and POPCNT ended up faster, as expected.
Results:
Intel(R) Core(TM) i7-4771 CPU max 3.90GHz
Timing (i & !(i & (i - 1))) trick
30
real 0m13.804s
user 0m13.799s
sys 0m0.000s
Timing POPCNT
30
real 0m11.916s
user 0m11.916s
sys 0m0.000s
AMD Ryzen Threadripper 2950X 16-Core Processor max 3.50GHz
Timing (i && !(i & (i - 1))) trick
30
real 0m13.675s
user 0m13.673s
sys 0m0.000s
Timing POPCNT
30
real 0m13.156s
user 0m13.153s
sys 0m0.000s
Note that here the Intel CPU seems slightly slower than AMD with the bit twiddling, but has a much faster POPCNT; the AMD POPCNT doesn't provide as much of a boost.
popcnt_test.c:
#include "stdio.h"
// Count # of integers that are powers of 2 up to 2^31;
int main() {
int n;
for (int z = 0; z < 20; z++){
n = 0;
for (unsigned long i = 0; i < 1<<30; i++) {
#ifdef USE_POPCNT
n += (__builtin_popcount(i)==1); // Was: if (__builtin_popcount(i) == 1) n++;
#else
n += (i && !(i & (i - 1))); // Was: if (i && !(i & (i - 1))) n++;
#endif
}
}
printf("%d\n", n);
return 0;
}
Run tests:
gcc popcnt_test.c -O3 -o test.exe
gcc popcnt_test.c -O3 -DUSE_POPCNT -mpopcnt -o test-popcnt.exe
echo "Timing (i && !(i & (i - 1))) trick"
time ./test.exe
echo
echo "Timing POPCNT"
time ./test-opt.exe
I see many answers are suggesting to return n && !(n & (n - 1)) but to my experience if the input values are negative it returns false values.
I will share another simple approach here since we know a power of two number have only one set bit so simply we will count number of set bit this will take O(log N) time.
while (n > 0) {
int count = 0;
n = n & (n - 1);
count++;
}
return count == 1;
Check this article to count no. of set bits
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;
}
}
This one returns if the number is the power of two up to 64 value ( you can change it inside for loop condition ("6" is for 2^6 is 64);
const isPowerOfTwo = (number) => {
let result = false;
for (let i = 1; i <= 6; i++) {
if (number === Math.pow(2, i)) {
result = true;
}
}
return result;
};
console.log(isPowerOfTwo(16));
console.log(isPowerOfTwo(10));
I've been reading the documentation for Random.nextInt(int bound) and saw this nice piece of code which checks whether the parameter is a power of 2, which says (part of the code) :
if ((bound & -bound) == bound) // ie, bouns is a power of 2
let's test it
for (int i=0; i<=8; i++) {
System.out.println(i+" = " + Integer.toBinaryString(i));
}
>>
0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
// the left most 0 bits where cut out of the output
for (int i=-1; i>=-8; i--) {
System.out.println(i+" = " + Integer.toBinaryString(i));
}
>>
-1 = 11111111111111111111111111111111
-2 = 11111111111111111111111111111110
-3 = 11111111111111111111111111111101
-4 = 11111111111111111111111111111100
-5 = 11111111111111111111111111111011
-6 = 11111111111111111111111111111010
-7 = 11111111111111111111111111111001
-8 = 11111111111111111111111111111000
did you notice something ?
power 2 number have the same bits in the positive and the negative binary representation, if we do a logical AND we get the same number :)
for (int i=0; i<=8; i++) {
System.out.println(i + " & " + (-i)+" = " + (i & (-i)));
}
>>
0 & 0 = 0
1 & -1 = 1
2 & -2 = 2
3 & -3 = 1
4 & -4 = 4
5 & -5 = 1
6 & -6 = 2
7 & -7 = 1
8 & -8 = 8
Kotlin:
fun isPowerOfTwo(n: Int): Boolean {
return (n > 0) && (n.and(n-1) == 0)
}
or
fun isPowerOfTwo(n: Int): Boolean {
if (n == 0) return false
return (n and (n - 1).inv()) == n
}
inv inverts the bits in this value.
Note:
log2 solution doesn't work for large numbers, like 536870912 ->
import kotlin.math.truncate
import kotlin.math.log2
fun isPowerOfTwo(n: Int): Boolean {
return (n > 0) && (log2(n.toDouble())) == truncate(log2(n.toDouble()))
}
There were a number of answers and posted links explaining why the n & (n-1) == 0 works for powers of 2, but I couldn't find any explanation of why it doesn't work for non-powers of 2, so I'm adding this just for completeness.
For n = 1 (2^0 = 1), 1 & 0 = 0, so we are fine.
For odd n > 1, there are at least 2 bits of 1 (left-most and right-most bits). Now n and n-1 will only differ by the right-most bit, so their &-sum will at least have a 1 on the left-most bit, so n & (n-1) != 0:
n: 1xxxx1 for odd n > 1
n-1: 1xxxx0
------
n & (n-1): 1xxxx0 != 0
Now for even n that is not a power of 2, we also have at least 2 bits of 1 (left-most and non-right-most). Here, n and n-1 will differ up to the right-most 1 bit, so their &-sum will also have at least a 1 on the left-most bit:
right-most 1 bit of n
v
n: 1xxxx100..00 for even n
n-1: 1xxxx011..11
------------
n & (n-1): 1xxxx000..00 != 0
I'm assuming 1 is a power of two, which it is, it's 2 to the power of zero
bool IsPowerOfTwo(ulong testValue)
{
ulong bitTest = 1;
while (bitTest != 0)
{
if (bitTest == testValue) return true;
bitTest = bitTest << 1;
}
return false;
}

Rotating numbers using modulus

I have a function (some kind of rotation) for argument i in [1001..999999] range:
int a = ((i - 1) % (1000000 - 1000) + 1001)
As you can see
i = 1001 a = 2001
...
i = 5000 a = 6000
...
i = 999999 a = 1999
I want to inverse this function, i.e. to have i = f(a), such that if, say, a = 6000 is given I want to have 5000 as a return etc. Unfortunately, I've experienced a problem with inversing % (modulo operation). Are there any suggestions in rotating numbers or reversing the above formula?
As you can see, since (1000000 - 1000) is quite greate a value, you get for (i - 1) % (1000000 - 1000) just two cases
i - 1 if i < 999001
i - 1 - 999001 if i >= 999001
And in order to inverse the formula, you have to analyze just these two cases only and you'll get as easy as
if (a > 2000)
return a - 1000;
else
return a + 998000;
Test
for (int i = 1001; i <= 999999; ++i) {
// forward, the formula from the question
int a = ((i - 1) % (1000000 - 1000) + 1001);
// ...and inverse one
int r = (a > 2000) ? a - 1000 : a + 998000;
// do we have reversed value != initial one?
if (r != i) {
// this will never happen
Console.Write("Counter example {0}", i);
break;
}
}

List collection that replaces numbers with words

I am trying to improve a list collection that i have to replace values that are divisible by two and 10 and replace everything that is divisible by two with dTwo and ten with dTen?
My code works with one divisible statment but not two.
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
num.Add(n % 10 == 0 ? "dTen" : n.ToString());
}
Since any number that is divisible by 10 is also divisible by 2 you have to switch your addition statements, and continue with the next number if you have a number divisible by 10:
var num = new List<string>();
for (int n = 0; n < 101; n++)
{
if( n % 10 == 0)
{
num.Add("dTen");
}
else num.Add(n % 2 == 0 ? "dTwo" : n.ToString());
}
If I can I try avoid using loop controls out side of the defined construct of the actual loop, ie. I prefer to avoid using continue if I can, it sort of feels like using goto statements. For this case, I would go for the plain and simple approach which I believe is readable, maintainable and simple albeit a little more verbose.
You can switch the order of the if/else if statements to change the priority if required, in this case the n % 10 has priority
var num = new List<string>();
for (int n = 0; n < 101; ++n)
{
if (n % 10 == 0)
{
num.Add("dTen");
}
else if (n % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(n.ToString());
}
}
There are two approaches I would take here, the first is verbose, but conveys what you're trying to do in a very readable manner:
var num = new List<string>(101);
for (int i = 0; i < 101 ; i++)
{
if (i == 0)
{
num.Add(i.ToString());
}
else if (i % 10 == 0)
{
num.Add("dTen");
}
else if (i % 2 == 0)
{
num.Add("dTwo");
}
else
{
num.Add(i.ToString());
}
}
The second uses a more concise LINQ-y type approach, like this.
var num = Enumerable.Range(0, 101)
.Select(
n => n == 0 ? n.ToString() :
n % 10 == 0 ? "dTen" :
n % 2 == 0 ? "dTwo" :
n.ToString())
.ToList();
Note that I've also taken into account the 0 edge case, where 0 would otherwise get reported as being divisible by 10.
Which one you go for is largely up to your taste. Personally I'd go for the latter implementation, as it's concise but still conveys the intent of the code. Some very rudimentary tests I've just done shows that it'll execute faster as well.

Count the numbers that are not divisible by 2, 3, 5

In my program, I think my count variable is not holding the value. What do I do so that it can hold? here`s my code.
static void Main(string[] args)
{
double a;
double count = 0;
Console.WriteLine("Enter the Numbers : ");
for (double i = 1; i <= 10; i++)
{
a = Convert.ToDouble(Console.ReadLine());
if (a % 2 != 0 || a % 3 != 0 || a % 5 != 0)
{
count = count++;
}
//else
//{
// }
Console.ReadLine();
}
Console.WriteLine("The Numbers That Are divisible by 2,3,5 are : " + count);
Console.ReadLine();
}
Your mistake is the line count = count++;. This does not increase count by one. You need to use just count++;.
The expression count++ will increment the value of count by one and then return as the expression's value the original value of count. In this case the increment of count++ happens before the assignment, so count is first incremented by one, but then you assign the value of count++, that is, the original value, to count again, so it does not increase at all.
Your program lists numbers that are not divisible by any of those numbers. If you want to count numbers which aren't divisible by all of them then you need to use if (a % 2 != 0 && a % 3 != 0 && a % 5 != 0) instead. I would also suggest using integers instead of doubles if possible.
Finally, your print statement says numbers that are divisible by 2,3,5, but count is the number of numbers which are not divisible by those numbers.
Edit: Are you entering 10 numbers each time you test? I'm not sure what kind of result you will get if you give a blank input.
Not to add to what jk and David Kanarek said in their answers or what the others the comments on those answers, As pointed out by jk use count+1 instead of count ++ , also a few notes:
1) Your using console.Readline() twice in the loop, so the user will enter 20 inputs but only 10 will be read..
2) Just alittle extra thought on Anton's comment, in your if clause , if you use || your trying to catch any of the conditions being true, in other words:
// a=2
if (a % 2 != 0 || a % 3 != 0 || a % 5 != 0) // False || True || True = True
{
count = count + 1 ;// count will increase
}
on the other hand, using && :
// a=2
if (a % 2 != 0 && a % 3 != 0 && a % 5 != 0) // False && True && True = false
{
count = count + 1 ; //count will not increase
}
A useful Link explaining operators

How to check if a number is a power of 2

Today I needed a simple algorithm for checking if a number is a power of 2.
The algorithm needs to be:
Simple
Correct for any ulong value.
I came up with this simple algorithm:
private bool IsPowerOfTwo(ulong number)
{
if (number == 0)
return false;
for (ulong power = 1; power > 0; power = power << 1)
{
// This for loop used shifting for powers of 2, meaning
// that the value will become 0 after the last shift
// (from binary 1000...0000 to 0000...0000) then, the 'for'
// loop will break out.
if (power == number)
return true;
if (power > number)
return false;
}
return false;
}
But then I thought: How about checking if log2 x is an exactly a round number? When I checked for 2^63+1, Math.Log() returned exactly 63 because of rounding. So I checked if 2 to the power 63 is equal to the original number and it is, because the calculation is done in doubles and not in exact numbers.
private bool IsPowerOfTwo_2(ulong number)
{
double log = Math.Log(number, 2);
double pow = Math.Pow(2, Math.Round(log));
return pow == number;
}
This returned true for the given wrong value: 9223372036854775809.
Is there a better algorithm?
There's a simple trick for this problem:
bool IsPowerOfTwo(ulong x)
{
return (x & (x - 1)) == 0;
}
Note, this function will report true for 0, which is not a power of 2. If you want to exclude that, here's how:
bool IsPowerOfTwo(ulong x)
{
return (x != 0) && ((x & (x - 1)) == 0);
}
Explanation
First and foremost the bitwise binary & operator from MSDN definition:
Binary & operators are predefined for the integral types and bool. For
integral types, & computes the logical bitwise AND of its operands.
For bool operands, & computes the logical AND of its operands; that
is, the result is true if and only if both its operands are true.
Now let's take a look at how this all plays out:
The function returns boolean (true / false) and accepts one incoming parameter of type unsigned long (x, in this case). Let us for the sake of simplicity assume that someone has passed the value 4 and called the function like so:
bool b = IsPowerOfTwo(4)
Now we replace each occurrence of x with 4:
return (4 != 0) && ((4 & (4-1)) == 0);
Well we already know that 4 != 0 evals to true, so far so good. But what about:
((4 & (4-1)) == 0)
This translates to this of course:
((4 & 3) == 0)
But what exactly is 4&3?
The binary representation of 4 is 100 and the binary representation of 3 is 011 (remember the & takes the binary representation of these numbers). So we have:
100 = 4
011 = 3
Imagine these values being stacked up much like elementary addition. The & operator says that if both values are equal to 1 then the result is 1, otherwise it is 0. So 1 & 1 = 1, 1 & 0 = 0, 0 & 0 = 0, and 0 & 1 = 0. So we do the math:
100
011
----
000
The result is simply 0. So we go back and look at what our return statement now translates to:
return (4 != 0) && ((4 & 3) == 0);
Which translates now to:
return true && (0 == 0);
return true && true;
We all know that true && true is simply true, and this shows that for our example, 4 is a power of 2.
Some sites that document and explain this and other bit twiddling hacks are:
http://graphics.stanford.edu/~seander/bithacks.html
(http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2)
http://bits.stephan-brumme.com/
(http://bits.stephan-brumme.com/isPowerOfTwo.html)
And the grandaddy of them, the book "Hacker's Delight" by Henry Warren, Jr.:
http://www.hackersdelight.org/
As Sean Anderson's page explains, the expression ((x & (x - 1)) == 0) incorrectly indicates that 0 is a power of 2. He suggests to use:
(!(x & (x - 1)) && x)
to correct that problem.
return (i & -i) == i
The following addendum to the accepted answer may be useful for some people:
A power of two, when expressed in binary, will always look like 1 followed by n zeroes where n is greater than or equal to 0. Ex:
Decimal Binary
1 1 (1 followed by 0 zero)
2 10 (1 followed by 1 zero)
4 100 (1 followed by 2 zeroes)
8 1000 (1 followed by 3 zeroes)
. .
. .
. .
and so on.
When we subtract 1 from these kind of numbers, they become 0 followed by n ones and again n is same as above. Ex:
Decimal Binary
1 - 1 = 0 0 (0 followed by 0 one)
2 - 1 = 1 01 (0 followed by 1 one)
4 - 1 = 3 011 (0 followed by 2 ones)
8 - 1 = 7 0111 (0 followed by 3 ones)
. .
. .
. .
and so on.
Coming to the crux
What happens when we do a bitwise AND of a number x, which is a
power of 2, and x - 1?
The one of x gets aligned with the zero of x - 1 and all the zeroes of x get aligned with ones of x - 1, causing the bitwise AND to result in 0. And that is how we have the single line answer mentioned above being right.
Further adding to the beauty of accepted answer above -
So, we have a property at our disposal now:
When we subtract 1 from any number, then in the binary representation the rightmost 1 will become 0 and all the zeroes to the left of that rightmost 1 will now become 1.
One awesome use of this property is in finding out - How many 1s are present in the binary representation of a given number? The short and sweet code to do that for a given integer x is:
byte count = 0;
for ( ; x != 0; x &= (x - 1)) count++;
Console.Write("Total ones in the binary representation of x = {0}", count);
Another aspect of numbers that can be proved from the concept explained above is "Can every positive number be represented as the sum of powers of 2?".
Yes, every positive number can be represented as the sum of powers of 2. For any number, take its binary representation. Ex: Take number 117.
The binary representation of 117 is 1110101
Because 1110101 = 1000000 + 100000 + 10000 + 0000 + 100 + 00 + 1
we have 117 = 64 + 32 + 16 + 0 + 4 + 0 + 1
bool IsPowerOfTwo(ulong x)
{
return x > 0 && (x & (x - 1)) == 0;
}
Here's a simple C++ solution:
bool IsPowerOfTwo( unsigned int i )
{
return std::bitset<32>(i).count() == 1;
}
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.
bool IsPowerOfTwo(int n)
{
if (n > 1)
{
while (n%2 == 0)
{
n >>= 1;
}
}
return n == 1;
}
And here's a general algorithm for finding out if a number is a power of another number.
bool IsPowerOf(int n,int b)
{
if (n > 1)
{
while (n % b == 0)
{
n /= b;
}
}
return n == 1;
}
bool isPow2 = ((x & ~(x-1))==x)? !!x : 0;
bool isPowerOfTwo(int x_)
{
register int bitpos, bitpos2;
asm ("bsrl %1,%0": "+r" (bitpos):"rm" (x_));
asm ("bsfl %1,%0": "+r" (bitpos2):"rm" (x_));
return bitpos > 0 && bitpos == bitpos2;
}
int isPowerOfTwo(unsigned int x)
{
return ((x != 0) && ((x & (~x + 1)) == x));
}
This is really fast. It takes about 6 minutes and 43 seconds to check all 2^32 integers.
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.
for any power of 2, the following also holds.
n&(-n)==n
NOTE: fails for n=0 , so need to check for it
Reason why this works is:
-n is the 2s complement of n. -n will have every bit to the left of rightmost set bit of n flipped compared to n. For powers of 2 there is only one set bit.
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;
}
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
Here is another method I devised, in this case using | instead of & :
bool is_power_of_2(ulong x) {
if(x == (1 << (sizeof(ulong)*8 -1) ) return true;
return (x > 0) && (x<<1 == (x|(x-1)) +1));
}
It's very easy in .Net 6 now.
using System.Numerics;
bool isPow2 = BitOperations.IsPow2(64); // sets true
Here is the documentation.
Example
0000 0001 Yes
0001 0001 No
Algorithm
Using a bit mask, divide NUM the variable in binary
IF R > 0 AND L > 0: Return FALSE
Otherwise, NUM becomes the one that is non-zero
IF NUM = 1: Return TRUE
Otherwise, go to Step 1
Complexity
Time ~ O(log(d)) where d is number of binary digits
There is a one liner in .NET 6
// IsPow2 evaluates whether the specified Int32 value is a power of two.
Console.WriteLine(BitOperations.IsPow2(128)); // True
Improving the answer of #user134548, without bits arithmetic:
public static bool IsPowerOfTwo(ulong n)
{
if (n % 2 != 0) return false; // is odd (can't be power of 2)
double exp = Math.Log(n, 2);
if (exp != Math.Floor(exp)) return false; // if exp is not integer, n can't be power
return Math.Pow(2, exp) == n;
}
This works fine for:
IsPowerOfTwo(9223372036854775809)
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.
in this approach , you can check if there is only 1 set bit in the integer and the integer is > 0 (c++).
bool is_pow_of_2(int n){
int count = 0;
for(int i = 0; i < 32; i++){
count += (n>>i & 1);
}
return count == 1 && n > 0;
}
I see many answers are suggesting to return n && !(n & (n - 1)) but to my experience if the input values are negative it returns false values.
I will share another simple approach here since we know a power of two number have only one set bit so simply we will count number of set bit this will take O(log N) time.
while (n > 0) {
int count = 0;
n = n & (n - 1);
count++;
}
return count == 1;
Check this article to count no. of set bits
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;
}
}
This one returns if the number is the power of two up to 64 value ( you can change it inside for loop condition ("6" is for 2^6 is 64);
const isPowerOfTwo = (number) => {
let result = false;
for (let i = 1; i <= 6; i++) {
if (number === Math.pow(2, i)) {
result = true;
}
}
return result;
};
console.log(isPowerOfTwo(16));
console.log(isPowerOfTwo(10));
I've been reading the documentation for Random.nextInt(int bound) and saw this nice piece of code which checks whether the parameter is a power of 2, which says (part of the code) :
if ((bound & -bound) == bound) // ie, bouns is a power of 2
let's test it
for (int i=0; i<=8; i++) {
System.out.println(i+" = " + Integer.toBinaryString(i));
}
>>
0 = 0
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
// the left most 0 bits where cut out of the output
for (int i=-1; i>=-8; i--) {
System.out.println(i+" = " + Integer.toBinaryString(i));
}
>>
-1 = 11111111111111111111111111111111
-2 = 11111111111111111111111111111110
-3 = 11111111111111111111111111111101
-4 = 11111111111111111111111111111100
-5 = 11111111111111111111111111111011
-6 = 11111111111111111111111111111010
-7 = 11111111111111111111111111111001
-8 = 11111111111111111111111111111000
did you notice something ?
power 2 number have the same bits in the positive and the negative binary representation, if we do a logical AND we get the same number :)
for (int i=0; i<=8; i++) {
System.out.println(i + " & " + (-i)+" = " + (i & (-i)));
}
>>
0 & 0 = 0
1 & -1 = 1
2 & -2 = 2
3 & -3 = 1
4 & -4 = 4
5 & -5 = 1
6 & -6 = 2
7 & -7 = 1
8 & -8 = 8
Kotlin:
fun isPowerOfTwo(n: Int): Boolean {
return (n > 0) && (n.and(n-1) == 0)
}
or
fun isPowerOfTwo(n: Int): Boolean {
if (n == 0) return false
return (n and (n - 1).inv()) == n
}
inv inverts the bits in this value.
Note:
log2 solution doesn't work for large numbers, like 536870912 ->
import kotlin.math.truncate
import kotlin.math.log2
fun isPowerOfTwo(n: Int): Boolean {
return (n > 0) && (log2(n.toDouble())) == truncate(log2(n.toDouble()))
}
There were a number of answers and posted links explaining why the n & (n-1) == 0 works for powers of 2, but I couldn't find any explanation of why it doesn't work for non-powers of 2, so I'm adding this just for completeness.
For n = 1 (2^0 = 1), 1 & 0 = 0, so we are fine.
For odd n > 1, there are at least 2 bits of 1 (left-most and right-most bits). Now n and n-1 will only differ by the right-most bit, so their &-sum will at least have a 1 on the left-most bit, so n & (n-1) != 0:
n: 1xxxx1 for odd n > 1
n-1: 1xxxx0
------
n & (n-1): 1xxxx0 != 0
Now for even n that is not a power of 2, we also have at least 2 bits of 1 (left-most and non-right-most). Here, n and n-1 will differ up to the right-most 1 bit, so their &-sum will also have at least a 1 on the left-most bit:
right-most 1 bit of n
v
n: 1xxxx100..00 for even n
n-1: 1xxxx011..11
------------
n & (n-1): 1xxxx000..00 != 0
I'm assuming 1 is a power of two, which it is, it's 2 to the power of zero
bool IsPowerOfTwo(ulong testValue)
{
ulong bitTest = 1;
while (bitTest != 0)
{
if (bitTest == testValue) return true;
bitTest = bitTest << 1;
}
return false;
}
In C, I tested the i && !(i & (i - 1) trick and compared it with __builtin_popcount(i), using gcc on Linux, with the -mpopcnt flag to be sure to use the CPU's POPCNT instruction. My test program counted the # of integers in the interval [0, 2^31) that were a power of two.
At first I thought that i && !(i & (i - 1) was 10% faster, even though I verified that POPCNT was used in the disassembly where I used__builtin_popcount.
However, I realized that I had included an if statement, and branch prediction was probably doing better on the bit twiddling version. I removed the if and POPCNT ended up faster, as expected.
Results:
Intel(R) Core(TM) i7-4771 CPU max 3.90GHz
Timing (i & !(i & (i - 1))) trick
30
real 0m13.804s
user 0m13.799s
sys 0m0.000s
Timing POPCNT
30
real 0m11.916s
user 0m11.916s
sys 0m0.000s
AMD Ryzen Threadripper 2950X 16-Core Processor max 3.50GHz
Timing (i && !(i & (i - 1))) trick
30
real 0m13.675s
user 0m13.673s
sys 0m0.000s
Timing POPCNT
30
real 0m13.156s
user 0m13.153s
sys 0m0.000s
Note that here the Intel CPU seems slightly slower than AMD with the bit twiddling, but has a much faster POPCNT; the AMD POPCNT doesn't provide as much of a boost.
popcnt_test.c:
#include "stdio.h"
// Count # of integers that are powers of 2 up to (not including) 2^31;
int main() {
int n;
for (int z = 0; z < 20; z++){
n = 0;
for (unsigned long i = 0; i < 1<<30; i++) {
#ifdef USE_POPCNT
n += (__builtin_popcount(i)==1); // Was: if (__builtin_popcount(i) == 1) n++;
#else
n += (i && !(i & (i - 1))); // Was: if (i && !(i & (i - 1))) n++;
#endif
}
}
printf("%d\n", n);
return 0;
}
Run tests:
gcc popcnt_test.c -O3 -o test.exe
gcc popcnt_test.c -O3 -DUSE_POPCNT -mpopcnt -o test-popcnt.exe
echo "Timing (i && !(i & (i - 1))) trick"
time ./test.exe
echo
echo "Timing POPCNT"
time ./test-opt.exe

Categories