cs240/sync/PreLab4/notes.txt

45 lines
2.4 KiB
Plaintext
Raw Normal View History

2018-10-15 17:20:57 -04:00
From http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/
8. Shift Right
This function is the equivalent of the Divide by Two algorithm. Dividing a binary integer by 2 is the same as shifting it right one bit, and checking whether a binary integer is odd is the same as checking if its least significant bit is 1.
int isPowerOfTwo (unsigned int x)
{
while (((x & 1) == 0) && x > 1) /* While x is even and > 1 */
x >>= 1;
return (x == 1);
}
The only way the statement “x == 1” becomes true is when there is only one 1 bit in x to start with.
9. Decrement and Compare
This function is a common one-liner youll find on the Web, and is how the check is implemented in malloc.c in the GNU C Library (glibc).
int isPowerOfTwo (unsigned int x)
{
return ((x != 0) && !(x & (x - 1)));
}
There are two halves to the expression: x != 0 and !(x & (x 1)). The first half makes 0 a special case, since the second half only works correctly for positive numbers. The second half — the interesting part of the expression — is true when x is a power of two and false when x is not. Lets see why.
Let n be the position of the leftmost 1 bit if x. If x is a power of two, its lone 1 bit is in position n. This means x 1 has a 0 in position n. To see why, recall how binary subtraction works. When subtracting 1 from x, the borrow propagates all the way to position n; bit n becomes 0 and all lower bits become 1. Now, since x has no 1 bits in common with x 1, x & (x 1) is 0, and !(x & (x 1)) is true.
Here are some examples (Ill use 8-bit unsigned integers to keep things manageable):
Decrement and Compare, when x is a power of two
x x 1 x & (x 1)
00000001 00000000 00000000
00000100 00000011 00000000
00010000 00001111 00000000
If x is not a power of two, x 1 has a 1 in position n. This is because the borrow will not propagate to position n. Subtraction borrows from the lowest 1 bit, which by virtue of x not being a power of two, is before position n. The lowest 1 bit is like a firewall that prevents the borrow from reaching position n. Since x and x 1 have at least one 1 bit in common — at position n — x & (x 1) is nonzero, and !(x & (x 1)) is false.
Here are some examples:
Decrement and Compare, when x is a NOT power of two
x x 1 x & (x 1)
00000011 00000010 00000010
00000110 00000101 00000100
00001011 00001010 00001010
00011100 00011011 00011000