I'm looking for an innovative way to check if a number has only one on bit in a signed int.
I am well aware that I can simply do a loop with a counter, some modular division, and a bit shift. But I'm curious if there is a better way since w开发者_如何学编程e are only looking for ONE bit to be on.
bool HasOnlyOneBit (int numb)
{
//return true if numb has only one bit (I.E. is equal to 1, 2, 4, 8, 16... Int.MinValue)
}
return x == (x & -x);
This answer works because of the way two's complement notation is designed.
First, an example. Assume we have 8-bit signed integers.
00010000 = 16
11110000 = -16
The bitwise and will give you 00010000
as a result, equal to your original value! The reason that this works is because when negating in 2's complement, first invert all the bits, then add 1. You'll have a bunch of zeros and a bunch of carries until a one falls into place. The bitwise and then checks if we have the right bit set.
In the case of a number that isn't a power of two:
00101010 = 42
& 11010110 = -42
----------
00000010 != 42
Your result will still have only a single bit, but it won't match the original value. Therefore your original value had multiple bits set.
Note: This technique returns true for 0, which may or may not be desirable.
This is a famous problem
(x & x-1) == 0
Power of 2 from Wiki : here
64 = 01000000 (x)
63 = 00111111 (x-1)
______________
& = 00000000 == 0
______________
Case when some other bits are ON
18 = 00010010 (x)
17 = 00010001 (x-1)
______________
& = 00010000 != 0
______________
I'd recommend you take a look at the Bit Twiddling Hacks page and choose the most suitable option under "Determining if an integer is a power of 2" or "Counting bits set".
return (x && ((x & x-1) == 0))
return (x && (0x8000000000000000ULL % x));
This is a simplification of the following code:
if (x == 0) {
return false;
} else if (0x8000000000000000ULL % x) {
return false;
} else {
return true;
}
Explanation: 0x8000000000000000 is the highest "1 bit only" value for an 64 bit register. Only a division by an other "1 bit only" value will result in no remainder.
Take the log to base 2 of your number, if it's an integer your number has only 1 1 bit. Not sure that I think this is better than any of your excluded options.
Python3 memory-efficient solution
return n > 0 and (n & (n-1)) == 0
精彩评论