"%" here is the
remainder after dividing by 2. Clearly it can only return 1 or 0. And happily that is just the value of the least significant bit.
'&' is the logical
and between each of the 32 bits
1 and 1 gives 1
1 and 0 gives 0
0 and 1 gives 0
0 and 0 gives 0
This is done for each of the 32 bit positions of the two operands.
In this case only the least significant bit is ever looked at because it is and'ed with one.
So and'ing a number with one sets all the bits above the first one to zero.
Here is what it looks like in binary, using a calculator:-
Code: Select all
>> 1
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 00000001 (0)
Oct 1, Dec 1, Hex 1, Ascii SOH, Roman I
>> 123
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 01111011 (0)
Oct 173, Dec 123, Hex 7B, Ascii '{', Roman CXXIII
>> 123 & 1
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 00000001 (0)
Oct 1, Dec 1, Hex 1, Ascii SOH, Roman I
>> 123 % 2
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 00000001 (0)
Oct 1, Dec 1, Hex 1, Ascii SOH, Roman I
For "123 & 1" you can see the far right bit is set for both numbers and so returns 1.
Code: Select all
>> 122
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 01111010 (0)
Oct 172, Dec 122, Hex 7A, Ascii 'z', Roman CXXII
>> 122 & 1
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 00000000 (0)
Oct 0, Dec 0, Hex 0, Ascii NUL
>> 122 % 2
Bin (63) 00000000 00000000 00000000 00000000 | 00000000 00000000 | 00000000 | 00000000 (0)
Oct 0, Dec 0, Hex 0, Ascii NUL
For "122 & 1" the far right bit is not set for 122, and so 0 must be returned - see the truth table above.
These are exactly the same as 123 remainder 2, or 122 remainder 2 (except that "and" is far far quicker to execute).
"remainder" on the Pi involves two costly instructions. First division (sdiv), then it multiplies the result and subtracts it from the original - using a special "multiply and subtract" instruction (mls).
"and" on the other hand is one single very fast instruction (one clock cycle or better).
On a Pi Zero division/remainder requires a library function call which is horribly slow.
Some programmers would have written:-
Code: Select all
if( n & 1 )
n = 3 * n + 1;
else
n >>= 1;
But of course a modern C compiler would make these obvious optimizations for you.