binary arithmetic…ugh
Looking through the gadget source code I’ve come across a snippet that
makes little sense to me:
if(((1 << P[n].Type) & (FOF_SECONDARY_LINK_TYPES)))
where we have ‘<<’ and ‘&’ as bitwise
operators.
This is nasty binary, another thing I have yet to learn for reasons
unknown.
So let’s go through some basics shall we? First what is binary? It’s a
simple code of 1s and 0s, or on & off switches. But how do those
represent numbers? Well each digit within the binary is a power of
two, or as Saju puts it 2^(number of trailing digits):
0001=1
0010=2
0100=4
1000=8
....
Each 0/1 is a bit, and there are 8bits to a byte. As an example
we can look at a short int, which is 2bytes. The binary representation
is simply 16 1s or 0s representing the number. Let’s look at some
binary examples and see how this works:
0011=2+1=3
1001=8+1=9
0110=4+2=6
1000001=2^6+1=65
Now that is under control, how does the “<<” work? This is called a
left shift, and basically moves everything to the left a specified
number of bits. What we have is “x << y” which means shift x to the
left by y bits.
1001 << 3 = 1001000 = 2^6 + 2^3 = 64 + 8 = 72
Our original problem shows that we will be shifting the binary value
of 1 by P[n].Type which will range anywhere from 0-5 in gadget.
1 << 0 = 001 << 0 = 000001 = 1
1 << 1 = 001 << 1 = 000010 = 2
1 << 2 = 001 << 2 = 000100 = 4
1 << 3 = 001 << 3 = 001000 = 8
1 << 4 = 001 << 4 = 010000 = 16
1 << 5 = 001 << 5 = 100000 = 32
Typically FOF_SECONDARY_LINK_TYPE = 2^0 + 2^4 = 1 + 16 = 17, which
means we are concerned with particle types 0 (gas) and 4 (stars). This
brings us to our next operator, the dirty little amperstamp. This is
referred to as the bitwise AND operator. From my understanding it
simply compares the each BIT between the two different values and if
they are both equal to 1 we have a match. So say we have (4 & 17), how
does this work? Well FIRST we have to do the left bitwise shift on 1
by 4 bits:
STARS:
00001 << 4 = 10000
[10000 & 10001]
10000 // 16 (STARS)
10001 // 17
----------------
10000 = 16 (MATCH)
GAS:
00001 << 0 = 00001
[00001 & 10001]
00001 // 1 (GAS)
10001 // 17
----------------
00001 = 1 (MATCH)
Now if we find a match, then the code continues into this if
statement, otherwise the condition check fails. As a quick example,
let’s perform this same operation for DM particles (Type 1):
DM:
00001 << 1 = 00010
[00010 & 10001]
00010 // 2 (DM)
10001 // 17
----------------
00000 = 0 (NO MATCH)
At first this made zero sense to me, but now I think I have a much
better grip on things. If I have further issues, Saju says to look at
this
link.