> C++ beginner. How to find whether a number is power of 2?

C++ beginner. How to find whether a number is power of 2?

Posted at: 2014-12-18 
Since you apparently don't want negative numbers, may as well define 'n' as an (unsigned int). So the following code will do what you want without floating point, logarithms, etc. Based on a simple twos-complement concept:

#include

using namespace std;

int main( ) {

? ? unsigned int n;

? ? if ( cin >> n ) cout << ((n & ~(n-1)) == n && n != 0? "YES" : "NO") << endl;

? ? return 0;

}

If you ever decide to allow floating point numbers, it would be best to simply test for a value != 0.0 and where the mantissa is all zero but the hidden bit is one. That will work for negative and positive powers. Something akin to the following should be okay for standard floating point formats:

#include

using namespace std;

bool n2( double x ) {

? ? unsigned long long int &p= *(unsigned long long int *) &x;

? ? unsigned int exp= (p >> 52) & 0x7FF;

? ? if ( exp == 0 || exp == 0x7FF ) return false;

? ? return (p & 0xFFFFFFFFFFFFFULL) == 0;

}

bool n2( float x ) {

? ? unsigned long int &p= *(unsigned long int *) &x;

? ? unsigned int exp= (p >> 23) & 0xFF;

? ? if ( exp == 0 || exp == 0xFF ) return false;

? ? return (p & 0x7FFFFFUL) == 0;

}

int main( ) {

? ? double n;

? ? if ( cin >> n ) cout << (n2( n )? "YES" : "NO") << endl;

? ? return 0;

}

The unfortunate presumption in the above code is that unsigned long long int will be 64 bits and that an unsigned long int is 32 bits. You can adjust the type to match these requirements for your C++ compiler.

EDIT in response to your comment:

You already have _Object's response. It's based upon basic knowledge about real numbers, (which floating point isn't, but that's another story), logarithms and exponents. He even explains difficulties with floating point tests. I have to assume that _Object's response is similarly overly-complex from your perspective. Otherwise, you'd have continued the discussion with him, not me.

Given that, let's take a very, very simple approach:

#include

using namespace std;

int main( ) {

? ? double n;

? ? if ( !(cin >> n) ) return 0;

? ? if ( n <= 0.0 )

? ? ? ? cout << "NO" << endl;

? ? else {

? ? ? ? while ( n < 1.0 ) n *= 2.0;

? ? ? ? while ( n >= 2.0 ) n /= 2.0;

? ? ? ? cout << (n == 1.0? "YES" : "NO") << endl;

? ? }

? ? return 0;

}

In the above code, I first verify that n > 0.0 because I think that's what you want. You don't want 0 or any negative numbers to say "YES." So that's taken care of immediately. If n > 0.0, then the 'important stuff' takes place on the double value (you can use float, as well.)

For numbers smaller than 1.0, you multiply them by 2 until they are at least 1.0. Since all such numbers are, by definition, less than 1.0 then multiplying them by 2 cannot cause them to become exactly 2.0. So this first loop transforms n such that 1.0 ≤ n < 2.0, in cases where n was initially less than 1.0.

For numbers equal to or larger than 2.0, you divide them down by 2 until they are less than 2.0. Since all such numbers are, by definition, at least 2.0 then dividing them by 2 cannot cause them to become less than 1.0. So this second loop transforms n such that 1.0 ≤ n < 2.0, in cases where n was initially 2.0 or larger.

In all cases now, 1.0 ≤ n < 2.0.

Now the test is obvious. If it is exactly 1.0 then the number was a power of 2. Otherwise, it wasn't. It should be obvious why, too. Only exact powers of 2 can be divided down or multiplied up, using only factors of 2, to get an exact 1.0.

A simple, exact test against 1.0 is probably "almost" safe here because ASCII text converted to exact powers of two technically 'should' be converted into a floating point value that is exact. And multiplication by 2.0 or division by 2.0 of such numbers technically 'should' continue to provide exact values. But if you want to worry just a little and just slightly widen the "gate" that allows a "YES" answer, then replace the above output line with:

? ? ? ? cout << (fabs( n - 1.0 ) < 1E-12? "YES" : "NO") << endl;

and make sure to add this include line:

#include

But as I said, it probably isn't necessary to go to that extreme in this specific case.

I hope this code makes more sense to you as a new programmer.

BY THE WAY. There is an IMPORTANT lesson here. You need to develop inside yourself the ability to imagine at least 6 ways to cut through any subject you've been handed. You can see that _Object has provided one slice. I've provided at least two more completely different ways that achieve the result. Don't imagine there aren't more -- there are at least two more ways that come immediately to mind and I've not given it much thought. You need to be equally flexible, creative, and imaginative when facing any given problem. If you can't come up with more than one way to approach any problem you are handed, large or small, then you still have a long way yet to come. Ask yourself why you were NOT able to come up with repeated multiplying or dividing by 2's. Think about it. I think if you'd have been forced to solve this problem yourself using nothing more than a calculator in hand, with people nearby hammering you with various numbers to test out, you'd have quickly come up with it on your own. I think so. So why didn't you come up with it here?

A power of 2 is always even, but a even number is not a power of 2. 6, for instance:

6 % 2 == 0, yet log_2 (6) is not an integer.

Also, the function fmod() is not declared in , which, as the name suggests, is just for input/output streams.

The C library is likely the most widely used software library in existence. Chances are you did not find a bug as glaring as a missing function.

Understand that for unsigned integers (positive powers of the form 2^n where n > 0), simply

! (k & (unsigned)(k - 1))

evaluates to true IFF k is a power of 2.

For n == 0, there is a corner case where underflow (0U - 1U == 0xFFFFFFFF) gives an incorrect result.

Unfortunately, powers of 2 include fractions (2^-2 == 1/4).

You could use more bitwise math, but that's very ugly because of the arrangement of bits in floating point.

Better to take the base 2 logarithm and check to see if it is an integer. Because of the way floating point values work, you'll get an integer as the result always, other values have issues with precision (you'll get 7.00001 instead of 7.00000, for instance).

This program works well.

Check:

# include

# include

int main(int, char **) {

? ? double k = 1.0 / 9223372036854775808.0; /* 2 ^ (-63) */

? ? std:: cout << std:: boolalpha

? ? ? ? ? ? << (0 == (log2 (k) - static_cast (log2 (k))))

? ? ? ? ? ? << std:: endl;

? ? return 0;

}

Beware the egde case at k = 0.

bro other r telling u very long answers....but mine will be way to simple and correct.

double a;

cin>>a;

while(a>1){

a=a/2;

}

if(a==1)

cout<<"Yes";

else

cout<<"No";

so,if u enter 32.it will divide again and again with 2 until it comes =1.so it will print yes

now in case of 31 it will divide again and again with 2 but it will never going to equal to 1.so it will print No

Your logic is flawed, now have fun finding where. It's not a compiler error. Hit the books.

EDIT:

HINT: What's the definition of a "power of 2"?

HINT2: cmath library?

HINT3: That program will not return yes for only powers of two, because of a few tests case (ex. the number 12) will be said to be a power of 2 according to that program, and it is NOT.

I'm pretty ignorant, unlike these other fellows. But couldn't you just examine the number's binary form, and claim that if the number was 1 with a bunch of zeros, it was a power of two, and otherwise, it wasn't? Like 0000 0010 is a power of 2, and so is 0000 1000, and 1000 0000, but 0000 0011 isn't?

>

> John (gnujohn)

http://mstechnologies.org/

The task:Take a number. Print YES, if it is a power of two, NO - otherwise.

my code:

#include

using namespace std;

int main()

{

int n; cin>>n;

if(n<=0)

cout<<"NO"<
while(n>1)

{

n=n/2;

if(n==1)

{cout<<"YES"<
break;}

if(n%2!=0)

{

cout<<"NO"<
break;}

}

}

The problem is that the % operator doesn't function with floats. And my compiler does not recognize fmod(). Please help .