Reputation: 61
I need to find out if int n is a power of two and my approach is to convert n to a hex number and check each bit (0 or 1). However, I've never used hex numbers in Java, could anyone help me out here?
Upvotes: 0
Views: 315
Reputation: 533482
Both converting to a String and replacing using a regular expression is expensive.
A simple way to check for a (positive) power of two is to check the number bits set.
if (x > 0 && Long.bitCount(x) == 1)
While Long.bitCount
looks complicated, the JVM can replace it with a single machine code instruction.
Upvotes: 1
Reputation: 64904
The canonical way (which you will encounter a lot when googling how to test for powers of two, and you will probably encounter it in code) to test for powers of two is
x != 0 && (x & x - 1) == 0
It is often encountered with more parenthesis (precedence paranoia?)
x != 0 && (x & (x - 1)) == 0
It is common to skip the x != 0
check and guarantee zero can't be an input, or (often enough) zero is "as good as" a power of two in some sense.
You can of course change the condition to x > 0
if you don't want to consider -2147483648 a power of two, though in many cases it would be (because it's congruent to 231 modulo 232, so interpreted unsigned it's a PoT, and anyway it only has one bit set so it was a PoT all along)
So what's the deal with x & x - 1
. It unsets the lowest set bit, but let's look at it in the context of PoTs.
Let's ignore x<2 and say x has the form a10k (ie an arbitrary string of bits followed by a one followed by k zeroes), subtracting 1 from it gives a01k because the -1 borrows through all the trailing zeroes until it reaches the lowest set bit, unsets that bit, then the borrow dies and the top bits are unchanged.
If you take the bitwise AND of a10k and a01k you get a00k because something ANDed with itself is itself again (the a
), and in the tail there's always a 0 involved in the AND so it's all zeroes.
Now there are two cases. 0) a=0. Then the result is zero, and we know we started out with x of the form 10k which is a power of two. And 1) a!=0, then the result isn't zero either because a
still appears in it, and x wasn't a power of two because it has at least two set bits (the lowest set bit which we explicitly looked at, and at least one other somewhere in a
).
Well actually there are two more cases, x=0 and x=1 which were ignored. If we allow k to be zero then x=1 is also included. x=0 is annoying though, in x & x - 1
there is that x
as the left operand of &
, so the result must be zero no matter what happens in the right operand. So it falls out as a special case.
Upvotes: 1
Reputation: 601
There is no reason to convert to hex to check bits. In fact, that actually makes it harder. The following line produces a binary String for an int variable "num":
String binary = Integer.toString(num, 2)
That String will only have 1s and 0s in it. Then eliminate any 0s:
String ones = binary.replace("0", "");
If the length of the String is more than one, there there is more than one bit, which means it is not a power of 2. If the length is 0, it means the number had no bits, which means it is 0.
Upvotes: 0