Understanding the bitwise AND Operator - objective-c

I have been reading about bit operators in Objective-C in Kochan's book, "Programming in Objective-C".
I am VERY confused about this part, although I have really understood most everything else presented to me thus far.
Here is a quote from the book:
The Bitwise AND Operator
Bitwise ANDing is frequently used for masking operations. That is, this operator can be used easily to set specific bits of a data item to 0. For example, the statement
w3 = w1 & 3;
assigns to w3 the value of w1 bitwise ANDed with the constant 3. This has the same ffect of setting all the bits in w, other than the rightmost two bits to 0 and preserving the rightmost two bits from w1.
As with all binary arithmetic operators in C, the binary bit operators can also be used as assignment operators by adding an equal sign. The statement
word &= 15;
therefore performs the same function as the following:
word = word & 15;
Additionally, it has the effect of setting all but the rightmost four bits of word to 0. When using constants in performing bitwise operations, it is usually more convenient to express the constants in either octal or hexadecimal notation.
OK, so that is what I'm trying to understand. Now, I'm extremely confused with pretty much this entire concept and I am just looking for a little clarification if anyone is willing to help me out on that.
When the book references "setting all the bits" now, all of the bits.. What exactly is a bit. Isn't that just a 0 or 1 in 2nd base, in other words, binary?
If so, why, in the first example, are all of the bits except the "rightmost 2" to 0? Is it 2 because it's 3 - 1, taking 3 from our constant?
Thanks!

Numbers can be expressed in binary like this:
3 = 000011
5 = 000101
10 = 001010
...etc. I'm going to assume you're familiar with binary.
Bitwise AND means to take two numbers, line them up on top of each other, and create a new number that has a 1 where both numbers have a 1 (everything else is 0).
For example:
3 => 00011
& 5 => 00101
------ -------
1 00001
Bitwise OR means to take two numbers, line them up on top of each other, and create a new number that has a 1 where either number has a 1 (everything else is 0).
For example:
3 => 00011
| 5 => 00101
------ -------
7 00111
Bitwise XOR (exclusive OR) means to take two numbers, line them up on top of each other, and create a new number that has a 1 where either number has a 1 AND the other number has a 0 (everything else is 0).
For example:
3 => 00011
^ 5 => 00101
------ -------
6 00110
Bitwise NOR (Not OR) means to take the Bitwise OR of two numbers, and then reverse everything (where there was a 0, there's now a 1, where there was a 1, there's now a 0).
Bitwise NAND (Not AND) means to take the Bitwise AND of two numbers, and then reverse everything (where there was a 0, there's now a 1, where there was a 1, there's now a 0).
Continuing: why does word &= 15 set all but the 4 rightmost bits to 0? You should be able to figure it out now...
n => abcdefghjikl
& 15 => 000000001111
------ --------------
? 00000000jikl
(0 AND a = 0, 0 AND b = 0, ... j AND 1 = j, i AND 1 = i, ...)
How is this useful? In many languages, we use things called "bitmasks". A bitmask is essentially a number that represents a whole bunch of smaller numbers combined together. We can combine numbers together using OR, and pull them apart using AND. For example:
int MagicMap = 1;
int MagicWand = 2;
int MagicHat = 4;
If I only have the map and the hat, I can express that as myInventoryBitmask = (MagicMap | MagicHat) and the result is my bitmask. If I don't have anything, then my bitmask is 0. If I want to see if I have my wand, then I can do:
int hasWand = (myInventoryBitmask & MagicWand);
if (hasWand > 0) {
printf("I have a wand\n");
} else {
printf("I don't have a wand\n");
}
Get it?
EDIT: more stuff
You'll also come across the "bitshift" operator: << and >>. This just means "shift everything left n bits" or "shift everything right n bits".
In other words:
1 << 3 = 0001 << 3 = 0001000 = 8
And:
8 >> 2 = 01000 >> 2 = 010 = 2

"Bit" is short for "binary digit". And yes, it's a 0 or 1. There are almost always 8 in a byte, and they're written kinda like decimal numbers are -- with the most significant digit on the left, and the least significant on the right.
In your example, w1 & 3 masks everything but the two least significant (rightmost) digits because 3, in binary, is 00000011. (2 + 1) The AND operation returns 0 if either bit being ANDed is 0, so everything but the last two bits are automatically 0.

w1 = ????...??ab
3 = 0000...0011
--------------------
& = 0000...00ab
0 & any bit N = 0
1 & any bit N = N
So, anything bitwise anded with 3 has all their bits except the last two set to 0. The last two bits, a and b in this case, are preserved.

#cHao & all: No! Bits are not numbers. They’re not zero or one!
Well, 0 and 1 are possible and valid interpretations. Zero and one is the typical interpretation.
But a bit is only a thing, representing a simple alternative. It says “it is” or “it is not”. It doesn’t say anything about the thing, the „it“, itself. It doesn’t tell, what thing it is.
In most cases this won’t bother you. You can take them for numbers (or parts, digits, of numbers) as you (or the combination of programming languages, cpu and other hardware, you know as being “typical”) usaly do – and maybe you’ll never have trouble with them.
But there is no principal problem if you switch the meaning of “0“ and “1”. Ok, if doing this while programming assembler, you’ll find it a bit problematic as some mnemonics will do other logic then they tell you with their names, numbers will be negated and such things.
Have a look at http://webdocs.cs.ualberta.ca/~amaral/courses/329/webslides/Topic2-DeMorganLaws/sld017.htm if you want.
Greetings

Related

Given no modulus or if even/odd function, how would one check for an odd or even number?

I have recently sat a computing exam in university in which we were never taught beforehand about the modulus function or any other check for odd/even function and we have no access to external documentation except our previous lecture notes. Is it possible to do this without these and how?
Bitwise AND (&)
Extract the last bit of the number using the bitwise AND operator. If the last bit is 1, then it's odd, else it's even. This is the simplest and most efficient way of testing it. Examples in some languages:
C / C++ / C#
bool is_even(int value) {
return (value & 1) == 0;
}
Java
public static boolean is_even(int value) {
return (value & 1) == 0;
}
Python
def is_even(value):
return (value & 1) == 0
I assume this is only for integer numbers as the concept of odd/even eludes me for floating point values.
For these integer numbers, the check of the Least Significant Bit (LSB) as proposed by Rotem is the most straightforward method, but there are many other ways to accomplish that.
For example, you could use the integer division operation as a test. This is one of the most basic operation which is implemented in virtually every platform. The result of an integer division is always another integer. For example:
>> x = int64( 13 ) ;
>> x / 2
ans =
7
Here I cast the value 13 as a int64 to make sure MATLAB treats the number as an integer instead of double data type.
Also here the result is actually rounded towards infinity to the next integral value. This is MATLAB specific implementation, other platform might round down but it does not matter for us as the only behavior we look for is the rounding, whichever way it goes. The rounding allow us to define the following behavior:
If a number is even: Dividing it by 2 will produce an exact result, such that if we multiply this result by 2, we obtain the original number.
If a number is odd: Dividing it by 2 will result in a rounded result, such that multiplying it by 2 will yield a different number than the original input.
Now you have the logic worked out, the code is pretty straightforward:
%% sample input
x = int64(42) ;
y = int64(43) ;
%% define the checking function
% uses only multiplication and division operator, no high level function
is_even = #(x) int64(x) == (int64(x)/2)*2 ;
And obvisouly, this will yield:
>> is_even(x)
ans =
1
>> is_even(y)
ans =
0
I found out from a fellow student how to solve this simplistically with maths instead of functions.
Using (-1)^n :
If n is odd then the outcome is -1
If n is even then the outcome is 1
This is some pretty out-of-the-box thinking, but it would be the only way to solve this without previous knowledge of complex functions including mod.

Boolean logic confusion

I do not fully understand the difference between a bitwise operation and a logical operation. Please see the bitwise operation below:
x=7 and 15
I understand that x will equal 7 in this case after inspecting each bit individually.
How does boolean logic work at a lower level. I believe that a Boolean is a 32 Bit data type (I could be wrong). Are boolean literals (TRUE and FALSE) treated as single bits?
Do not make any assumption about the internal structure of a Boolean. In many languages (i.e. C, C++), bool is internally represented as int and everything except the value 0 is interpreted as true. But this is impmentation-dependent and may change between compilers or even compiler versions. In modern languages such as java or c#, (the equivalent of) the above statement will not even compile, because an int cannot be implicitly cast to a bool.
If you really need bitwise operation, the statement is of course valid, the value of x will be 7 (as this is the bitwise and of 7 and 15), but to convert this to Boolean, it would be wise to do it explicitly, i.e if (x != 0) then... or bool xb = x != 0. This might help avoiding confusion to the reader of your code and also makes clear that you're aware of the fact that you're now doing a type conversion.
This is generally how these things work.
Bitwise operations perform Boolean operations on the bits representing their operands. Logical operations are Boolean operations performed on Boolean sets, usually TRUE and FALSE or 1 and 0. A Boolean set could be any group of distinct items where the total count of set members is 2.
In the case of performing bitwise AND on the operands 7 and 15: if the system you're using represents them as straight binary numbers with no weird offsets then 7 becomes 0111 in binary, 15 becomes 1111 in binary. The leading 0 on binary 7 is not necessary as it is the same as prepending a zero to any decimal number: 10 = 010 = 000000000000010, it's easier to illustrate the operation with the leading zero though.
0111 7 in binary
1111 15 in binary
&&&& bitwise AND
0111 results in 7
if true and false are represented as binary 1 and 0 then there is no difference between the "logical" and and the "bitwise" and operations.
1 true as binary 1
0 false as binary 0
& either logical or bitwise AND
0 results in binary 0
try bitwise and on some other numbers like say 1 and 2
01 1 in binary
10 2 in binary
&& bitwise and
00 results in binary 0
Assuming that any number except 0 will be converted to true, performing a "logical" and on the numbers 1 and 2 would yield a different result
1 the number 1 converted to true and represented as boolean 1
1 the number 2 converted to true and represented as boolean 1
& logical and
1 results in true, here represented as binary 1
When performing bitwise operations involving floats, negative numbers, or basically anything other than positive whole numbers, you may end up with radically different results. This is due to different environments using different methods for storing numbers in memory. For sure, it's all binary but, the number line isn't always centered on binary zero and it's not always the case that every bit represents part of the number; some of the bits could represent the sign of the number or the exponent. You'll have to dig down into the implementation details if you want to just toss decimal numbers into bitwise operations. It's easier to deal with if you have a method of converting the numbers to binary because then you know the bits and their order exactly and, you'll be able to test whether your expectations match your results.

Objective - C - Usage of << in enumeration

I can see in Apple's documentation that enumerations are sometimes defined like this
enum {
UICollectionViewScrollPositionTop = 1 << 0,
UICollectionViewScrollPositionBottom = 1 << 1
}
What does the << mean?
It's the bitwise shift left operator. It's used to create values having a single bit set, very common when combination through bitwise OR is intended.
For those values, you might later say:
const int top_and_bottom = UICollectionViewScrollPositionTop | UICollectionViewScrollPositionBottom;
which would result in top_and_bottom being set to 3 (binary 112).
Here it is simply left bit shift. So this means 1<<0 = 1 for instance. And 1<<1 is two. Maybe the author chose this way to initialize the enumeration to emphasize on the fact that UICollectionViewScrollPositionTop has only the least significant bit on and UICollectionViewScrollPositionBottom has only the second to least significant bit on. I guess the usage for this enumeration is to somehow later form bitmasks.
<< stands for left shift.
It shifts the binary to specified bits, as 4<<1 will be 8 and 4<<2 will be 16.
Each left shift makes the value multiplied by 2.
1<<0 will be 1 while 1<<1 will be 2.
Check here

How to test a bit in a decimal number

I have a set of decimal numbers. I need to check if a specific bit is set in each of them. If the bit is set, I need to return 1, otherwise return 0.
I am looking for a simple and fast way to do that.
Say, for example, I am checking if the third bit is set. I can do (number AND (2^2)), it will return 4 if the bit is set, otherwise it will return 0. How do I make it to return 1 instead of 4?
Thank you!
if ((number AND (2^bitnumber) <> 0) then return 1 else return 0 end if
If you can change your return type to boolean then this is more elegant
return ((number AND (2^bitnumber)) <> 0)
While the division solution is a simple one, I would think a bit-shift operation would be more efficient. You'd have to test it to be sure, though. For instance, if you are using 1 based bit indexes, you could do this:
Dim oneOrZero As Integer = (k And 2 ^ (n - 1)) >> (n - 1)
(Where k is the number and n is the bit index). Of, if you are using 0 based bit indexes, you could just do this:
Dim oneOrZero As Integer = (k And 2 ^ n) >> n
Sorry, guys, I am too slow today.
To test a bit number "n" in a decimal number "k":
(k AND 2^(n-1))/(2^(n-1))
will return 1 if the bit is set, otherwise will return 0.
=====================================================
Hi again, guys!
I compared the performance of the three proposed solutions with zero-based indexes, and here are the results:
"bit-shift solution" - 8.31 seconds
"if...then solution" - 8.44 seconds
"division solution" - 9.41 seconds
The times are average of the four consecutive runs.
Surprisingly for me, the second solution outperformed the third one.
However, after I modified the "division solution" this way:
p = 2 ^ n : oneOrZero = (k And p) / p
it started to run in 7.48 seconds.
So, this is the fastest of the proposed solutions (despite of what Keith says :-).
Thanks everybody for the help!
I really don't know if it can help anyone more than the above, but, here we go.
When I need to fast check a bit in number I compare the decimal-value of this bit directly.
I mean, if I would need to see of the 6th bit is on (32), I check its decimal value, like this:
if x and 32 = 32 then "the bit is ON"
Try for instance check 38 with 32, 4 and 2... and the other bits.
You will see only the actual bits turned on.
I hope it can help.
Yes! Simply use a bit mask. I enumerate the bits, then AND the number with the bit value. Very little math on the PC side as it uses lookup tables instead. The AND basically shuts off all the other bits except the one you are interested in. Then you check it against itself to see if it's on/off.
Enum validate
bit1 = 1
bit2 = 2
bit3 = 4
bit4 = 8
bit5 = 16
bit6 = 32
bit7 = 64
bit8 = 128
End Enum
If num And validate.bit3 = validate.bit3 Then true

What do the operators '<<' and '>>' do?

I was following 'A tour of GO` on http://tour.golang.org.
The table 15 has some code that I cannot understand. It defines two constants with the following syntax:
const (
Big = 1<<100
Small = Big>>99
)
And it's not clear at all to me what it means. I tried to modify the code and run it with different values, to record the change, but I was not able to understand what is going on there.
Then, it uses that operator again on table 24. It defines a variable with the following syntax:
MaxInt uint64 = 1<<64 - 1
And when it prints the variable, it prints:
uint64(18446744073709551615)
Where uint64 is the type. But I can't understand where 18446744073709551615 comes from.
They are Go's bitwise shift operators.
Here's a good explanation of how they work for C (they work in the same way in several languages).
Basically 1<<64 - 1 corresponds to 2^64 -1, = 18446744073709551615.
Think of it this way. In decimal if you start from 001 (which is 10^0) and then shift the 1 to the left, you end up with 010, which is 10^1. If you shift it again you end with 100, which is 10^2. So shifting to the left is equivalent to multiplying by 10 as many times as the times you shift.
In binary it's the same thing, but in base 2, so 1<<64 means multiplying by 2 64 times (i.e. 2 ^ 64).
That's the same as in all languages of the C family : a bit shift.
See http://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts
This operation is commonly used to multiply or divide an unsigned integer by powers of 2 :
b := a >> 1 // divides by 2
1<<100 is simply 2^100 (that's Big).
1<<64-1 is 2⁶⁴-1, and that's the biggest integer you can represent in 64 bits (by the way you can't represent 1<<64 as a 64 bits int and the point of table 15 is to demonstrate that you can have it in numerical constants anyway in Go).
The >> and << are logical shift operations. You can see more about those here:
http://en.wikipedia.org/wiki/Logical_shift
Also, you can check all the Go operators in their webpage
It's a logical shift:
every bit in the operand is simply moved a given number of bit
positions, and the vacant bit-positions are filled in, usually with
zeros
Go Operators:
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer