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.
Related
fmt.Println(^1)
Why does this print -2?
The ^ operator is the bitwise complement operator. Spec: Arithmetic operators:
For integer operands, the unary operators +, -, and ^ are defined as follows:
+x is 0 + x
-x negation is 0 - x
^x bitwise complement is m ^ x with m = "all bits set to 1" for unsigned x
and m = -1 for signed x
So 1 in binary is a single 1 bit preceded with full of zeros:
0000000000000000000000000000000000000000000000000000000000000001
So the bitwise complement is a single 0 bit preceded by full of ones:
1111111111111111111111111111111111111111111111111111111111111110
The ^1 is an untyped constant expression. When it is passed to a function, it has to be converted to a type. Since 1 is an untyped integer constant, its default type int will be used. int in Go is represented using the 2's complement where negative numbers start with a 1. The number being full ones is -1, the number being smaller by one (in binary) is -2 etc.
The bit pattern above is the 2's complement representation of -2.
To print the bit patterns and type, use this code:
fmt.Println(^1)
fmt.Printf("%T\n", ^1)
fmt.Printf("%064b\n", 1)
i := ^1
fmt.Printf("%064b\n", uint(i))
It outputs (try it on the Go Playground):
-2
int
0000000000000000000000000000000000000000000000000000000000000001
1111111111111111111111111111111111111111111111111111111111111110
Okay, this has to do with the way that we use signed signs in computation.
For a 1 byte number, you can get
D
B
-8
1000
-7
1001
-6
1010
-5
1011
-4
1100
-3
1101
-2
1110
-1
1111
0
0000
1
0001
2
0010
3
0011
4
0100
5
0101
6
0110
7
0111
You can see here that 1 is equivalent to 0001 (Nothing changes) but -1 is equal to 1111. ^ operator does a bitwise xor operation. Therefore:
0001
1111 xor
-------
1110 -> That is actually -2.
All this is because of the convention of two complement that we use to do calculations with negative numbers. Of course, this can be extrapolated to longer binary numbers.
You can test this by using windows calculator to do a xor bitwise calculation.
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
Is there a way to find a logic gate or how to make a more complex gate / bit operator from a wanted truth table
I wish to have this truth table :
0 0 = 1
0 1 = 1
1 0 = 0
1 1 = 1
There is a formal way of doing this if you cannot see it from the table.
Write the sum of products expression for the table.
If 0 0 = 1, then A'B' is in the expression.
If 0 1 = 1, then A'B is in the expression.
If 1 1 = 1, then AB is in the expression.
Then, F = A'B' + A'B + AB
Now, simplify the expression:
F = A'B' + A'B + AB
F = A'(B'+B) + AB Distribution Law
F = A'(1) + AB Complement Law
F = A' + AB Identity Law
F = A'(B + 1) + AB Annulment Law
F = A'B + A' + AB Distribution Law
F = (A' + A)B + A' Distribution Law
F = (1)B + A' Complement Law
F = B + A' Identity Law
It is not(A) or B.
You have to use a not gate and an or gate.
Alternative Solution
As pointed out in the comments, you can come up from the negated version of the function.
If 1 0 = 0, then F' = AB'
Simply, F = not(A and not(B)). If you distribute the not, then it will correspond to the same boolean expression as above.
Thanks to the comments for pointing out the shorter way.
The truth table gives exactly one possibility for 0. This is the same pattern as with the OR operator (also one possibility for 0), except that the first operand should then be flipped. So it follows that the first operand should be negated to get the desired result:
NOT(A) OR B
This is actually the implication operator: the expression is false when and only if the first operand is true and the second not:
A => B
If we represent an operator with the 4 outcome bits for operands 00, 01, 10, and 11, then this operator has code 1101 (read the output column from top to bottom). For all possible operations we have this:
Output
Expression
0000
FALSE
0001
A AND B
0010
A AND NOT(B)
0011
A
0100
NOT(A) AND B
0101
B
0110
A XOR B
0111
A OR B
1000
NOT(A OR B)
1001
A <=> B
1010
NOT B
1011
B => A
1100
NOT A
1101
A => B
1110
NOT(A AND B)
1111
TRUE
There are many alternative ways to write these expressions, but as a rule of thumb: if you need three 1-outputs, look for an OR operator where potentially one or both arguments need to be flipped. If you need one 1-output, do the same with an AND operator. If you have two 1-outputs, do the same with a XOR (or <=>) operator, unless it is a trivial case where one of the operands determines the result on its own.
if your input is X1 and X2 and you want to have a 1 as output, you can look at the combination which is easy to define: threre is only one 0 - and then invert it
the case for output 0: x1 and (not (x2) )
invert the solution (de Mogan): not (x1 and (not (x2) )) = not(x1) or x2
You need 1 x not and 1 x or
or you need 2 x not and 1 x and
I need to find a greatest number, x for given y and n such that x ^ y <= n
Here n can be very large number - 1 <= n <= 10^10
and 1 <= y <= 10^5
for example :
for y = 5 and n = 1024
x ^ 5, then x = 4 (4 ^ 5 = 1024)
for y = 5 and n = 480
x ^ 5 , then x = 3 (3 ^ 5 = 243, 4 ^ 5 = 1024) - selecting lowest one, so x = 3
i have written a small program, But i want more efficient technique because n and y can be very large.
def get(y, n):
x = 1
while x ** y <= n:
x += 1
return x - 1
Using a multiple-precision arithmetic library, such as gmpy2's iroot.
>>> import gmpy2
>>> root, exact = gmpy2.iroot(n, y)
This is simply an integer n-th root algorithm. It should be fast and correct even for huge numbers (something that floats cannot guarantee in the general case).
The second value returned is a boolean which indicates if the root is exact or not.
>>> print(*gmpy2.iroot(1024, 5))
4 True
>>> print(*gmpy2.iroot(480, 5))
3 False
you can use binary search on integer to move from your O(x) to O(log(x)) if you apply floating math then:
x^y = n // ^(1/y)
x = n^1/y
x = floor(pow(n,1/y))
your example n=400 and y=5 is like this:
x = floor(pow(400,1/5))
x = floor(pow(400,0.2))
x = floor(3.3144540173399868004685801443126)
x = 3
of coarse for big n will this not work with basic floating types. In such case either use bin search on big integers or implement your own bigint pow if you do not have it already at your disposal. Anyway both approaches are described here:
Power by squaring for negative exponents do not get fouled by the title it is all integer math ...
[edit1]
after absorbing your comments:
n = < 1 , 10^10 >
y = < 1 , 10^5 >
no FPU just integer math
I would use binary search. You need to use at least ceil(log2(10^10))=34 bit variables for this so unsigned 64 bit QWORD it is. if you do not have such variables you need to implement it from lower bit width variables first.
The binary search mask will be:
m = 2^33 = 1<<33 = 0x0000000200000000
so you first need to implement pow and then root adapting code from linked answer here is C++ result:
#define T_bits 34
#define T_MSB 0x0000000200000000
#define T QWORD
T pow(T x,T y) // power by squaring returns z=x^y where x>=0, y>=0
{
T i,z=1;
for (i=0;i<T_bits;i++) // test all bits from MSB to LSB
{
z*=z;
if (T(y&T_MSB)) z*=x;
y<<=1;
}
return z;
}
T bits(T x) // count how many bits is in x
{
T m=T_MSB,z=T_bits;
for (;m;m>>=1,z--)
if (x>=m) break;
return z;
}
T root(T x,T y) // bin search y-th root returns z=x^(1/y)
{
T m,z;
m=((bits(x)+y-1)/y); // ceil(bits(x)/y)
if (m) m=1<<m; else m=1; // MSB of the result for bin search 2^(ceil(bits(x)/y))
for (z=0;m;m>>=1) // test all bits of x from MSB to LSB
{
z|=m; // set actual bit
if (pow(z,y)>x) z^=m; // clear if result exceedes x
}
return z;
}
for those of you that have just 32 bit arithmetics and have lover limit n<2^32 change the defines to:
#define T_bits 32
#define T_MSB 0x80000000
#define T DWORD
or use any other variable type you got at your disposal. The T is your data-type T_MSB is MSB bit set and T_bits is used bit count.
If you use:
root(400,5);
it will return 3. You can use your ** instead of pow I can not as my compiler does not recognize ** operator. Now to explanation of binary search
let assume your example. You start with x=1 then test x=2 then x=3 and so on until you cross x^y>=n so in reality you had checked pow(n,1/y) values. if we use n=10000, y=2 that will lead to 100 tests.
The binary search does not increment but set individual bits instead. 10000 has 14 bits so ceil(14/y)=7 so the process will be:
x with set bit| x^y | action
-------------------------------
0100 0000 bin | 4096 | none
0110 0000 bin | 9216 | none
0111 0000 bin | 12544 | clear
0110 1000 bin | 10816 | clear
0110 0100 bin | 10000 | none
0110 0010 bin | 10404 | clear
0110 0001 bin | 10201 | clear
-------------------------------
0110 0000 bin | 10000 | result
leading to only 7 tests instead of your naive 100.
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