What does & do in ruby (between integers) - ruby

I would like to know what & does in the use case:
7 & 3
=> 3
8 & 3
=> 0
Or as seen in the general use case:
Integer & Integer
=> ??
I know that array & array2 gives the intersection between the two arrays, but I am unsure of exactly what is going on here when used with integers.

& is bitwise AND which examines the two operands bit-by-bit and sets each result bit to 1 if both the corresponding input bits are 1, and 0 otherwise. You can also think of it as bit-by-bit multiplication.
111 (7)
AND 011 (3)
------------
= 011 (3)
1000 (8)
AND 0011 (3)
------------
= 0000 (0)

Related

Is there an algorithm to bit shift every n-long bits from a number without overflow?

For example, if I have a number 0101 1111 and I want to shift every 4 bit long section to the left to get 1010 1110. While I could just modulo off each section to get two 4-bit numbers, is there an algorithm that doesn't need to do this?
A naive approach
A first naive appraoch is to slice the 4 bit groups and process them individually. The expected result is obtained with the following for the first group of 4 bits.
(((x & 0xf) // take only 4 bits
<< 1) // shift them by 1
& 0xf) // get rid of potential overflow
For the n+1 th group of 4 bits, it's
(((x & (0xf<<(n*4)))
<< 1)
& (0xf<<(n*4)))
Since this is designed, so that there is no overlap around the 4 bits that are processed, you could iterate, and binary-or the partial results.
A less naive approach
Another approach is to simply shift the full x by 1, causing every 4 bit group to be shifted at once:
0101 1111 -> 1011 1110
We can then easily get rid of the overflow, and at the same time make sure that 0's are injected on the left, by clearing every 4th bit in the result of the shift:
1011 1110
& 1110 1110
---------
1010 1110
1110 is e in hexadecimal. So you need to generate a number with as many 0xe as there are 4 bit segments. In your case it's 0xee if it's just 8 bits. It's 0xeeeeeeeeeeeeeeee if it's 64 bits. Someone told this answer in the comments. Here you have the explanation.
Caution if your underlying data type is signed, because of the sign bit. Do this processing on unsigned integers to avoid any surprise.
Here is one way.
int bits = 0b1111_0001_0011_0111;
int result = 0;
int m = 0b1111;
while(m != 0) {
result |= ((bits & m) << 1) & m;
m <<= 4;
}
System.out.printf("%-7s = %s%n","src", Integer.toBinaryString(bits));
System.out.printf("%-7s = %s%n","result", Integer.toBinaryString(result));
Prints
src = 1111000100110111
result = 1110001001101110

different between "&" and "and" in expressions [duplicate]

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.

Marching cube, bitwise and and OR

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

How to find largest power of 2 a number is divisible by using logic functions?

How do you find the largest power of 2 a number is divisible by using logic function
for example 144 is divisible by 16 which is 2^4.
How would one do this.
I know 144 in binary is 1001 0000 and I have to use a bitwise function.
But what would I use (and or andn orn ?) or perhaps something else and what can I use as my mask?
I know you have to look at the right most number to tell if it is divisible by 2.
Any help is appreciated
I would go with n & -n or with n & (~n + 1), in case you are worried about running across one's complement arithmetic, given the latter works with both arithmetics.
E.g.,
> 144 & (~144 + 1)
< 16
Now a short explanation.
The bitwise NOT (i.e., ~ operator) of a number n gives -(n + 1). It inverts all the bits of n. The number 2 is represented by 00000010 while its negation is 11111101 which equals to -3 (i.e., , see the two's complement representation of signed numbers).
Do not to confuse it with logical negation.
E.g., ~144 = -(144 + 1) = -145.
The bitwise AND (i.e., & operator) compares two bits of the inputs and generates a result of 1 if both are 1, otherwise it returns 0.
Now the main topic.
This is an old tricks that gives the highest power of 2 that n is divisible by. This means that it returns a number with a single one bit, specifically the bottom bit that was set in n.
For example the binary representation of 144 is 010010000. Its bottom 1 bit is the bit in fourth position (counting backward from right and starting at position 0). Thus the higher power of 2 that divides 144 is 16 (i.e., 00010000).
144 & (~144 + 1) = 144 & -144 = 16
16 & ( ~16 + 1) = 16 & - 16 = 16
10 & ( ~10 + 1) = 10 & - 10 = 2
12 & ( ~12 + 1) = 12 & - 12 = 4
11 & ( ~11 + 1) = 11 & - 11 = 1
3 & ( ~ 3 + 1) = 3 & - 3 = 1
Note that if n is not divisible by any power of 2 it returns 1.
Why it works?
The negative of n is produced by inverting its bits via ~, then adding 1 (again, see two's complement definition). This sum causes every 1 bit (starting from the bottom) to overflow until a 0 bit is encountered (let us call it the bit x). Here the overflow process stops, leaving remaining bits (those beyond the current x bit) unchanged. Thus performing & between n and its inverse will result in a binary string containing only the x bit.
An example follows.
010010000 | +144 ~
----------|-------
101101111 | -145 +
1 |
----------|-------
101110000 | -144
101110000 | -144 &
010010000 | +144
----------|-------
000010000 | 16

Query about working out whether number is a power of 2

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.

Resources