0% found this document useful (0 votes)
33 views2 pages

Bit

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views2 pages

Bit

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 2

Bitwise Operators We commonly use the binary operators && and ||, which take the logical and

and
logical or of two boolean expressions. Since boolean logic can work with single bits, C provides operators
that work on individual bits within a variable. As we learned earlier in the semester, if we store an int in
binary with the value 47, its last eight binary bits are as follows: 00101111 Similarly, 72 in binary is
01001000. Bitwise operators would take each corresponding bit in the two input numbers and calculate
the output of the same operation on each set of bits. For example, a bitwise AND is represented with a
single ampersand sign: &. This operation is carried out by taking the and of two bits. If both bits are one,
the answer is one. Otherwise, the answer is zero. Here is the bitwise and operation on 47 and 72: 0 0 1 0
1 1 1 1 & 0 1 0 0 1 0 0 0 --------------------- 0 0 0 0 1 0 0 0 (which has a value of 8.) Thus, the following code
segment has the output 8: int x = 47, y = 72; int z = x & y; printf(“%d”, z); Here is a chart of the other
bitwise operators: Function Operator Meaning and & 1&1 = 1, rest = 0 or | 0 | 0 = 0, rest = 1 xor ^ 1 ^ 0 =
0 ^ 1 = 1 0 ^ 0 = 1 ^ 1 = 0 Not (unary operator) ~ ~0 = 1, ~1 = 0 Now, let’s calculate the other bitwise
operations between 47 and 72: 0 0 1 0 1 1 1 1 | 0 1 0 0 1 0 0 0 --------------------- 0 1 1 0 1 1 1 1 (which has
a value of 111.) 0 0 1 0 1 1 1 1 ^ 0 1 0 0 1 0 0 0 --------------------- 0 1 1 0 0 1 1 1 (which has a value of 103.)
Two’s Complement In order to understand exactly how the bitwise not operator works on integers, we
must understand exactly how a signed integer is stored inside the computer. Regular binary notation,
which we learned earlier, is used to store unsigned integers (these don’t allow for negative values and
are used less frequently than regular ints). Two’s Complement is used to store regular ints. The storage
scheme is almost identical to regular binary, except for the meaning of the most significant bit. An int is
stored using 32 bits. For an unsigned number, each of these bits are place-holders with value 231, 230,
229 , …, 22 , 21 , and 20 . Essentially, if the bit at location i is 1, then we contribute 2i to the value of the
number. (If it’s 0, nothing changes.) In two’s complement, we only change the most significant bit to
mean -2 31 . For example, if all of the bits were 1 in a regular int: 11111111 11111111 11111111
11111111 Then, the value of this number would be: -2 31 + 230 + 229 + 228 + … + 22 + 21 + 20 = -1.
From here, we can get to other negative values by turning some of the bits off. For example, it’s fairly
easy to see that -5 would be represented as follows: 11111111 11111111 11111111 11111011 Taking
into account two’s complement, we can calculate the effect of the bitwise not operator. Consider
calculating ~x, where x = 47, from our previous example. Here is all 32 bits of x: 00000000 00000000
00000000 00101111 Flipping each bit, we get: 11111111 11111111 11111111 11010000 Using a bit of
logic, we can see that if we were to have all 1’s the value would be -1. But, now that we’ve turned off the
bits that add up to 47, our new value will be -48. In essence, we see that in the typical case, when x is
positive, ~x is equal to –x-1. Hopefully you can see that if x is negative, then ~x is ALSO –x-1. (Thus, ~~x
always equals x, as you might imagine.) Left and Right Shift Operators The left-shift operator is <>. When
we left-shift a value, we must specify how many bits to leftshift it. What a left-shift does is move each bit
in the number to the left a certain number of places. In essence, so long as there is no overflow, a left-
shift of one bit multiplies a number by two (since each bit will be worth twice as much). It follows that a
left shift of 2 bits multiplies a number by 4 and a left shift of 3 bits multiples a number by 8. In general, a
left-shift of k bits multiplies a number by 2k . Using bitwise operators to iterate through subsets Imagine
solving the following problem with brute force: Given an array of values, such as {9, 3, 4, 5, 12}, does
there exist a subset of values in the array that adds up to a target, say 22? Our goal would be simply to
try EACH possible subset of the array, add the values and see if we get the target. If we think about
binary and look at the binary values from 0 to 31, we have: 00000 01000 10000 11000 00001 01001
10001 11001 00010 01010 10010 11010 00011 01011 10011 11011 00100 01100 10100 11100 00101
01101 10101 11101 00110 01110 10110 11110 00111 01111 10111 11111 If we assume that 0 means,
“don’t put this number in the set” and 1 means, “put this number in the set, then these 32 listings
represent all possible subsets of a set of 5 values. Thus, our idea is as follows: Loop from 0 to 31, for each
value and calculate the sum of the corresponding subset. For example, since 13 is 01101, this means that
the subset we want to add up is array[3], array[2] and array[0]. We are using the most significant bit in
the number to correspond to the last array slot and the least significant bit in the number to correspond
to index 0 in the array. In this example, when we are considering 13, the values we add are 9, 4 and 5 to
obtain 18. Here is the code that does this: int i, j; int n = 5; int array[] = {9, 3, 4, 5, 12}; int target = 22; for
(i=0; i < (1 << n); i++) { int sum = 0; for (j=0; j < n; j++) if ( (i & (1 << j)) != 0 ) sum += array[j]; if (sum ==
target) printf(“Can add up to the target!\n”); } Notes: 1) Remember that a left-shift of n bits multiplies by
2n , so the value of 1 << n for this example is 25 = 32, as desired. 2) The j loop is going through each array
element, trying to decide whether or not to add it. The value 1 << j has only one bit set to 1, it’s the bit at
location j. 3) If we do a bitwise and with a number of the form 000…001000…, then our answer will
either be all 0s OR it will be the number itself. Basically, all of the 0s cancel out the other 31 bits. The one
1 isolates that particular bit, which is exactly what we want

You might also like