1)so we have the N amount of numbers for example : 3 then we have numbers 8 ,4 ,7 . And i want code which will be able to cout the amount of numbers which is the power of 2 from this list.
you can do it with a log base 2 if you want. (cmath log2() function, you don't even need the change of base stuff for the common logs (e, 2, and 10 for sure are supported, not sure what else).
all the powers of 2 are a single bit, right? 1 (2^0), 2 (10) 4 (100) 8 (1000) ... see any pattern you could exploit there? alternately you can use a lookup table (think <map>) -- there are only 64 values in a 64 bit number.
#include <iostream>
usingnamespace std;
bool isPowerOfp( unsigned n, int p )
{
return n == 1 || ( n > 1 && !( n % p ) && isPowerOfp( n / p, p ) );
}
int main()
{
for ( int i = 0; i <= 32; i++ ) cout << i << ": " << boolalpha << isPowerOfp( i, 2 ) << '\n';
}
gcc has a function __builtin_popcount, which returns the number of bits set in a number. A positive power of two will have exactly one bit set when represented as ant integer.
1 2
if (__builtin_popcount(number) == 1)
//number is a power of two.
Something like this should work with any compiler and be very fast:
1 2
if ((number-1)&number == 0)
//number is a power of two.
It works because (number-1) toggles the leftmost bit only if number is a power of two.
1 2 3 4 5 6 7 8 9 10 11
#include <iostream>
int main()
{
int n;
while (std::cin >> n)
{
std::cout << n << " is " << ((n-1)&n ? " not " : "") << "a power of two.\n";
}
return 0;
}
Edit: this doesn't work on zero. You could fix this by checking if the number is zero.
you want to determine whether a given value is a binomial coefficient?
"powers of 2" and "binomial coefficients" are two very different things.
Your answer will go into an inifinte loop if the input is 0. Even if it didn't, the final shift after the loop will cause it to consider 0 to be a power of 2. So maybe something like this:
1 2 3 4 5
bool is_pow2(unsignedlong n) {
while (n > 1 && n & 1 == 0)
n >>= 1;
return n == 1;
}
It's really just salem.c's idea translated from arithmetic to bitshifting operations.
That's interesting. So div_by_2 and shift_right are about the same, as we might suspect on a modern machine. But it's ridiculous that dec_and_cmp (a neat little trick) beats the intrinsic, which, if it can't use an appropriate CPU instruction should at least be able to use the dec_and_cmp trick itself (or is there a potential pitfall in that trick?). And clang++ seems to know something the others don't!
But it's ridiculous that dec_and_cmp (a neat little trick) beats the intrinsic, which, if it can't use an appropriate CPU instruction should at least be able to use the dec_and_cmp trick itself (or is there a potential pitfall in that trick?).
The figures that JLBorges posted shows that popcount and dec_and_cmp are about the same with GCC. Have you done your own testing and found that this is not the case?
And clang++ seems to know something the others don't!
The Compiler Explorer link shows that both Clang and GCC generates the same code for is_pow2_popcount and is_pow2_dec_and_cmp, at least for that specific hardware. The difference seem to be that when the function is called inside a loop Clang decides to generate vector instructions (simd) while GCC doesn't. https://gcc.godbolt.org/z/P8x4SR
This sort of optimization will not be possible in all real-world use cases.
I was just going by his results. You're right that for both GCC and MS they are very close, but I would've expected popcount to be faster as I was assuming there would be a CPU instruction for it. But I guess there isn't (at least on that machine).
That's interesting about clang and the vector instructions. Thanks for pointing that out. I guess I should've followed the links.
you guys have me beat so far. This is really cool. log and map both slower. I expected that for the map, but I thought log would actually be a contender.
I have a hackish contender :( its slower and uglier, but not that much slower.
and I just realized it isnt right either. Same bit set in 2 bytes and it will give the wrong answer. Back to the drawing board it is. Not going to beat a cpu instruction, regardless.
I think I am going to surrender this one. I was thinking there would be a way to do it in less N operations (adding up the bits, eg the shifting answer) without using the cpu instruction using logic but I can't find it. I was able to get it with a bit more work but it was a lot more than 8 operations (per byte) and a lot more expensive than the shifts which are so cheap.