I've been looking at algorithms that list all the possible combinations of an array of boolean values.
For example, an array of two booleans can have these combinations:
[true, true], [true, false], [false, true], [false, false]
I've found several examples that use bitwise operators and whilst I've looked up the definitions of the operators used, I still don't understand their contextual use in the algorithms.
I've listed an example algorithm (source: http://zacg.github.io/blog/2013/08/02/binary-combinations-in-javascript/) below with annotations to describe what I'm seeing when I look at them:
function binaryCombos(n){
var result = [];
for(y=0; y<Math.pow(2,n); y++){ // This cycles through the maximum number of combinations
(power of 2 because it's binary)
var combo = []; // combo for particular iteration, eventually pushed to result
for(x=0; x<n; x++){ // iterate over number of booleans in array
//shift bit and and it with 1
if((y >> x) & 1) // right shifts and then masks for 1? i.e. tests if it's odd??
combo.push(true); // I don't see how this ensures all combiantions are covered
else
combo.push(false); // I don't understand the criteria for pushing false or true :(
}
result.push(combo);
}
return result;
}
//Usage
combos = binaryCombos(3);
for(x=0; x<combos.length; x++){ // This looks like driver code so have been ignoring this
console.log(combos[x].join(','));
}
Here's an example working with n = 2:
y = 0
x = 0
0 >> 0 is still 0 so will evaluate to false when 'anded' with 1 as:
0000 0000
& 0000 0001 --> 0
'false' pushed to combo array
y=0
x=1
0 >> 1 still 0 and will push 'false' to combo array
pushed to results: [false, false]
y=1
x=0
1 >> 0 equates to 0000 0001 with no shift(?) so 'anding' with 1 will evaluate to true,
'true' pushed to combo array
y=1
x=1
1 >> 1 is the same as halving but would eval to 0 so false is pushed to combo array
pushed to results: [true, false]
y=2
x=0
2 >> 0 equates to false being pushed to combo array as 0000 0010 & 0000 0001 = 0
y=2
x=1
2 >> 1 equates to true being pushed as 0000 0001 & 0000 0001 = 1
pushed to results: [false, true]
y=3
x=0
3 >> 0 equates to true being pushed to combo array since 0000 0011 & 0000 0001 = 1
y=3
x=1
3 >> 1 equates to true being pushed to combo array
pushed to results: [true, true]
result returned: [[false, false], [true, false], [false, true], [true, true]]
I can intuitively see that nested loops will help solve permutations and I can recognize that this has arrived at the correct answer but can't see the relationship between shifting y by x and then 'anding' with comprehensively covering all combinations.
Any help appreciated!
x is a (zero-based) bit number. That bit number refers to a bit in the binary representation of y: the least significant bit has number 0 (at the right of the binary representation), and the most significant bit has number n-1. As a combination has n boolean values, the bit representation (of y) has n bits. A zero-bit translates to false and a 1-bit to true.
Now, to extract the xth bit from the binary representation of y, we can use the shift operator:
y >> x
After this operation, the bit we are interested in has moved all the way to the right. All the bits that were at the right of the xth bit have "fallen of" by this >> operation. What remains is to get rid of all the bits at the left of the bit we want to extract. For that we use & 1. That's all that is needed to isolate the xth bit of the binary representation of y.
Example
Let's say we have n=4 and the outer loop has iterated to the point where y=13. The binary representation of y is 1101.
The loop on x will start with x=0, so the shift operation will not do anything, but the & 1 operation will extract the right-most bit of 1101, i.e. 1.
The next inner iteration will have x=1. Now the shift operation will kick that right most bit out, and we are left with 110. The & 1 operation will now extract the 0. And so it continues for x=3 and x=4.
Here represented in a table (for n=4 and y=13):
y
x
y >> x
(y >> x) & 1
boolean
1101
0
1101
1
true
1101
1
110
0
false
1101
2
11
1
true
1101
3
1
1
true
Related
This question already has answers here:
Boolean operators vs Bitwise operators
(9 answers)
Closed 4 months ago.
What the different between logical operators and, or and bitwise analogs &, | in usage? Is there any difference in efficiency in various solutions?
Logical operators operate on logical values, while bitwise operators operate on integer bits. Stop thinking about performance, and use them for they're meant for.
if x and y: # logical operation
...
z = z & 0xFF # bitwise operation
Bitwise = Bit by bit checking
# Example
Bitwise AND: 1011 & 0101 = 0001
Bitwise OR: 1011 | 0101 = 1111
Logical = Logical checking or in other words, you can say True/False checking
# Example
# both are non-zero so the result is True
Logical AND: 1011 && 0101 = 1 (True)
# one number is zero so the result is False
Logical AND: 1011 && 0000 = 0 (False)
# one number is non-zero so the result is non-zero which is True
Logical OR: 1011 || 0000 = 1 (True)
# both numbers are zero so the result is zero which is False
Logical OR: 0000 || 0000 = 0 (False)
Logical operators are used for booleans, since true equals 1 and false equals 0. If you use (binary) numbers other than 1 and 0, then any number that's not zero becomes a one. Ex: int x = 5; (101 in binary) int y = 0; (0 in binary) In this case, printing x && y would print 0, because 101 was changed to 1, and 0 was kept at zero: this is the same as printing true && false, which returns false (0). On the other hand, bitwise operators perform an operation on every single bit of the two operands (hence the term "bitwise"). Ex: int x = 5; int y = 8; printing x | y (bitwise OR) would calculate this: 000101 (5)| 1000 (8) ----------- = 1101 (13) Meaning it would print 13.
In order to understand marching cube algorithm, I followed this page:
http://paulbourke.net/geometry/polygonise/
I have some questions:
what do bitwise & and | mean?, and how they will work with edge table to find the correct tringles?
if (grid.val[0] < isolevel) cubeindex |= 1;
if (edgeTable[cubeindex] & 1)
vertlist[0] =
VertexInterp(isolevel,grid.p[0],grid.p[1],grid.val[0],grid.val[1]);
Not going to read that text thats way to long. But here you can find how bit operators work https://en.wikipedia.org/wiki/Bitwise_operations_in_C. `
cubeindex |= 1 --> cubeindex = cubeindex | 1.
for example cubeindex = 26 (binary 11010) and 1 (binary 00001)
11010 | 00001 = 11011
Here you ad one 26->27.
For the followingedgeTable[cubeindex] & 1:
For example cubeindex = 17 (binary 10001) \
10001 & 00001 = 00001
This becomes 1. Used in the if statement, this just checks if the number edgeTable[cubeindex] contains the bit 00001 and returns true or false accordingly.
hope this helps :)
Cheers
Bitwise & (and) and | (or) operate on all the bits within an integer value. It operates on each bit independently, and is often used with you have a set of boolean truth values (aka flags) that indicate the state of various objects. It can also be used (as in your example) or test a specific flag while not modifying the others.
The bits in an integer represent powers of two values. If that bit is set to true, then that power of two is included in its value. If that bit is false, then it is no included. The least significant bit b0 represents 2^0, bit 1 represents 2^1, and so on.
For example, the value 5 = 101 in binary because 5 = 2^2 + 2^0 = 4 + 1 = 5
Bitwise OR works by setting the bits in the result to 1 if either of the operands contains a one in that position. Bitwise AND workds by setting each bit to 1 if and only if both operands have a 1 in that position.
For example:
Bitwise OR: 5 | 9 = 0101 | 1001 = 1101
Bitwise AND: 5 & 9 = 0101 & 1001 = 0001
Using these operators, if the set of bit values in cubeindex represent a set of states(true or false values), then you can use the same bitwise operands to test and if a specific state is true, while ignoring the other bits.
In your example:
cubeindex |= 1
sets the least significant bit in cubeindex to true (1) regardless of what it was before. This is because the bitwise OR of any bit value to 0, is the same bit value, while the bitwise OR of any bit value of 1, is always 1 and so is the same as setting that bit to 1 regardless of its previous stae. It is equivalent to:
cubeindex = cubeindex | 000000000000000001 = cubeindex with b0 set to 1
The logical AND is being used to test if the least significant bit of edgeTable[cubeindex] equals 1. The condition is only true if the b0 of this value is 1. Why? Because the other bits do not matter since they are being bitwise AND with zero, which is always zero.
edgeTable[cubeindex] & 1 = value of bit 0
Assume you are given n distinct numbers, which may or may not have a gap in between them. If you were to XOR all the numbers, the result that you get, would it be be guaranteed to not be any of those n numbers?
0b00 XOR 0b01 XOR 0b10 XOR 0b11 == 0b00
No.
Assuming you meant that the first number in the array will be XOR'd with the 2nd, and the result of that would be XOR'd with the 3rd, etc, then consider the below counterpoint:
[1,2,6,4]
Using a binary XOR, see below bit representations:
100 XOR 010 = 110
110 XOR 011 = 101
101 XOR 001 = 100
The XOR of all the numbers in the array is equal to the first number in the array.
The number 0 has a pretty interesting trait in this context:
a xor 0 = a, a != 0
This is already half of the answer to the question:
XOR-ing the content of any set {a, 0}, a != 0 would yield a as result. Thus the answer is no.
This can be expanded even further:
For any set of numbers N, where a subset M with the properties M = N \ {a} and xor(M) = 0 exists, xor(N) = a holds. M has the property that the number of 1bits on any bit-position would be even:
N = {100, 010, 001, 011}
a = 100
M = {010, 001, 011}
M: 0 1 0
0 0 1
0 1 1
count: 0 2 2
xor(N) = 100
This is task from algorithms book.
The thing is that I completely don't know where to start!
Trace the following non-recursive algorithm to generate the binary reflexive
Gray code of order 4. Start with the n-bit string of all 0’s.
For i = 1, 2, ... 2^n-1, generate the i-th bit string by flipping bit b in the
previous bit string, where b is the position of the least significant 1 in the
binary representation of i.
So I know the Gray code for 1 bit should be 0 1, for 2 00 01 11 10 etc.
Many questions
1) Do I know that for n = 1 I can start of with 0 1?
2) How should I understand "start with the n-bit string of all 0's"?
3) "Previous bit string"? Which string is the "previous"? Previous means from lower n-bit? (for instance for n=2, previous is the one from n=1)?
4) How do I even convert 1-bit strings to 2-bit strings if the only operation there is to flip?
This confuses me a lot. The only "human" method I understand so far is: take sets from lower n-bit, duplicate them, invert the 2nd set, add 0's to every element in 1st set, add 1's do every elements in 2nd set. Done (example: 0 1 -> 0 1 | 0 1 -> 0 1 | 1 0 -> 00 01 | 11 10 -> 11 01 11 10 done.
Thanks for any help
The answer to all four your questions is that this algorithm does not start with lower values of n. All strings it generates have the same length, and the i-th (for i = 1, ..., 2n-1) string is generated from the (i-1)-th one.
Here is the fist few steps for n = 4:
Start with G0 = 0000
To generate G1, flip 0-th bit in G0, as 0 is the position of the least significant 1 in the binary representation of 1 = 0001b. G1 = 0001.
To generate G2, flip 1-st bit in G1, as 1 is the position of the least significant 1 in the binary representation of 2 = 0010b. G2 = 0011.
To generate G3, flip 0-th bit in G2, as 0 is the position of the least significant 1 in the binary representation of 3 = 0011b. G3 = 0010.
To generate G4, flip 2-nd bit in G3, as 2 is the position of the least significant 1 in the binary representation of 4 = 0100b. G4 = 0110.
To generate G5, flip 0-th bit in G4, as 0 is the position of the least significant 1 in the binary representation of 5 = 0101b. G5 = 0111.
Using the classic code snippet:
if (x & (x-1)) == 0
If the answer is 1, then it is false and not a power of 2. However, working on 5 (not a power of 2) and 4 results in:
0001 1111
0001 1111
0000 1111
That's 4 1s.
Working on 8 and 7:
1111 1111
0111 1111
0111 1111
The 0 is first, but we have 4.
In this link (http://www.exploringbinary.com/ten-ways-to-check-if-an-integer-is-a-power-of-two-in-c/) for both cases, the answer starts with 0 and there is a variable number of 0s/1s. How does this answer whether the number is a power of 2?
You need refresh yourself on how binary works. 5 is not represented as 0001 1111 (5 bits on), it's represented as 0000 0101 (2^2 + 2^0), and 4 is likewise not 0000 1111 (4 bits on) but rather 0000 0100 (2^2). The numbers you wrote are actually in unary.
Wikipedia, as usual, has a pretty thorough overview.
Any power of two number can be represent in binary with a single 1 and multiple 0s.
eg.
10000(16)
1000(8)
100(4)
If you subtract 1 from any power of two number, you will get all 1s to the right of where the original one was.
10000(16) - 1 = 01111(15)
ANDing these two numbers will give you 0 every time.
In the case of a non-power of two number, subtracting one will leave at least one "1" unchanged somewhere in the number like:
10010(18) - 1 = 10001(17)
ANDing these two will result in
10000(16) != 0
Keep in mind that if x is a power of 2, there is exactly 1 bit set. Subtract 1, and you know two things: the resulting value is not a power of two, and the bit that was set is no longer set. So, when you do a bitwise and &, every bit that was set in x is not unset, and all the bits in (x-1) that are set must be matched against bits not set in x. So the and of each bit is always 0.
In other words, for any bit pattern, you are guaranteed that (x&(x-1)) is zero.
((n & (n-1)) == 0)
It checks whether the value of “n” is a power of 2.
Example:
if n = 8, the bit representation is 1000
n & (n-1) = (1000) & ( 0111) = (0000)
So it return zero only if its value is in power of 2.
The only exception to this is ‘0’.
0 & (0-1) = 0 but ‘0’ is not the power of two.
Why does this make sense?
Imagine what happens when you subtract 1 from a string of bits. You read from left to right,
turning each 0 to a 1 until you hit a 1, at which point that bit is flipped:
1000100100 -> (subtract 1) -> 1000100011
Thus, every bit, up through the first 1, is flipped. If there’s exactly one 1 in the number, then every bit (other than the leading zeros) will be flipped. Thus, n & (n-1) == 0 if there’s exactly one 1. If there’s exactly one 1, then it must be a power of two.