Write A Function To Determine If A Number Is A Power Of 2
skorks.com
skorks.com
IF NOT(MOD(X,2)) THEN...
2000: a senior programmer, using OP's slick bit flipping approach: def power_of_2?(number)
number != 0 && number & (number - 1) == 0
end
2010: either a master or a lazy programmer, having pity on whoever has to maintain it: if !(mod(x,2)) then ...
Now that clock speeds are so much faster, can we all just go back to being lazy and focus on the real problem at hand?[EDIT: Oops, I confused "power of 2" with "divisible by 2", rendering my entire comment stupid and pointless. But I won't delete it because so much is hanging below it already. This is a perfect example of what we hackers can never allow ourselves to do: wave our hands at the trees because we're so busy looking at the forest. I promise I won't do this again, at least until tomorrow. Now I'm going to close my browser and get back to work :-) ]
if !(mod(x,2) {
if (x == 1) return true else return false;
}else return is_power_of_2(x/2);
or if !(mod(x,2) {
if (x == 1) return true;
if ((x > 1) || (x == 0)) return false;
return is_power_of_2(x * 2);
}else if (x > 2) return is_power_of_2(x/2) else return false;
PS: 2^0 = 1 and 2^-1 so you could have 3 versions of this fuction.You're right, though, the original question itself is not so much of a problem, I suppose. What bothered me is the subtext that, unless you get down to the bit level with the minimum possible number of CPU instructions in the result and do the compiler's job yourself, you're not a "real programmer" or something.
I make no qualms about wanting to hire programmers that "get" what's going on down below.
Bit tricks like these are one of the reasons I love working on a few microcontroller projects each year. It's too easy to get lazy and sloppy when you have multiple GB of RAM and multi-GHz CPUs at your disposal. Coding for a microcontroller with 2KB of flash and 128 bytes of RAM forces you to carefully evaluate the architecture of your code and find the most efficient way of solving your problems. From my experience, that tight-code thought process tends to stick with me when I return to bigger projects in higher-level languages.
http://www.amazon.com/Hackers-Delight-Henry-S-Warren/dp/0201...
which should be on every serious programmers bookshelf. Take a look, also, at the wonderful MIT HackMem report. Its Wikipedia entry, http://en.wikipedia.org/wiki/HAKMEM, has pointers to online versions. The venerable PDP-10's influence shows, but there's lots of cool stuff there.
Knuth's Art of Computer Programming,read closely, occasionally divulges clever hacks, particularly in the exercises.
bool isPowerOf2(unsigned int n) {
return __builtin_popcount(n) == 1;
} int ispoweroftwo(float x) {
return !(*(int*)(&x) << 9);
}
This only works for exact powers of two, though. It's possible to get something that's really close that will fail this.Absolute value of a signed it:
a= x >> 32
return (a + x)^a
Swap values of two ints without a temporary int:
a^=b
b^=a
a^=b
! operator (boolean not) without any boolean operators:
int a = x | (~x +1);
int b = a >> 31;
return b + 1;
There were a ton of interesting problems. Made for a great assignment.
a= x >> 32
return (a + x)^a
Careful; right-shifting by >= the size of the type is an undefined operation, and might not do what you expect in all cases. (For instance, it might do nothing at all on x86, as integer shifts/rotations in ia32 are all performed modulo 32.)I'm not against testing, but I find many people using testing that excessively, start using it as an excuse not to bother thinking about if their solutions are correct or not.
>>> from math import log
>>> def isPower2(val): return False if (val == 0) else (log(val) / log(2)).is_integer()
...
>>> isPower2(0)
False
>>> isPower2(1)
True
>>> isPower2(2)
True
>>> isPower2(3)
False
>>> isPower2(4)
True
>>> isPower2(1024)
True
>>> isPower2(1025)
False static unsigned int mylog2 (unsigned int val) {
unsigned int ret = -1;
while (val != 0) {
val >>= 1;
ret++;
}
return ret;
}
Faster log2() (thanks to [1]): static const char LogTable256[256] =
{
#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
-1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
};
unsigned int v; // 32-bit word to find the log of
unsigned r; // r will be lg(v)
register unsigned int t, tt; // temporaries
if (tt = v >> 16)
{
r = (t = tt >> 8) ? 24 + LogTable256[t] : 16 + LogTable256[tt];
}
else
{
r = (t = v >> 8) ? 8 + LogTable256[t] : LogTable256[v];
}
Fastest log2() on x86: #include <stdint.h>
static inline uint32_t log2(const uint32_t x) {
uint32_t y;
asm ( "\tbsr %1, %0\n"
: "=r"(y)
: "r" (x)
);
return y;
}
On ARM, one can replace bsr with clz.You can figure out that a logarithm in base 2 is easy to compute in base 2 arithmetic (sounds kinda obvious, too); it's the position of the most significant bit set.
Now someone needs to come and point out that BSR has a latency 16 times that of AND, and 4 times the throughput. Touche, gentlemen.
[1] http://graphics.stanford.edu/~seander/bithacks.html#IntegerL...
Floating point gets you approximate answers.
>>> isPower2(2**31)
False
mutter why no preview button on HN mutterThey want to know that you know what sorts of inputs to start testing on (empty input, if that's valid, each obvious corner case (can you find all the corner cases quickly? This is a good skill to have), etc.) and that you can do this mentally a little before you compile and run the tests.
Take the modulus and do the bitwise check!
If you go by the Two's complement representation, then for a negative number say (-8), because of sign extention, a check for x&(x-1) would fail.
bool powerOf2(int a){
return !(a & (a-1));
}