![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 | |
|
Newbie
Join Date: Apr 2008
Posts: 23
Rep Power: 0
![]() |
Bitwise Operators...
I have read/looked through like 2 books and 1 online guide about "bitwise operators" such as >> and <<... I just can't express the amount of confusion I have towards these operators xD.
Example: Quote:
So if someone could explain them more in-depth, more importantly how they are used and what the outcome becomes , that would be great ^_^.-- Them being the commands like >>, &, << and |. |
|
|
|
|
|
|
#2 |
|
Battle Programmer
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 751
Rep Power: 3
![]() |
Re: Bitwise Operators...
Bitwise operators work on the specific bits of the value you're modifying. For this reason they'll only work on integer types (floating point numbers are fancy magic). Here's a rough explanation of some of them work (using 8 bit values):
Bitwise shift (<<, >>) just shifts the bits one way or another. Examples: left shift: 5<<2: 5 in binary is 00000101 shifted left twice is 00010100, which in decimal is 20 signed: -16 >> 2 (aka, arithmetic shift which preserves signed-ness bit) -16 in binary is 11110000 shifted right two times is 11111100, which in decimal is -4 132 in binary is 10000100 shifted right 4 times is 11111000, which in decimal is 248 signed: -16 >>> 2 (note: not C syntax, this wouldn't happen in C for signed values) -16 in binary is 11110000 shifted right two times is 00111100, which in decimal is 60 132 in binary is 10000100 shifted right 4 times is 00001000, which in decimal is 16 The AND operator is pretty simple. It compares each corresponding bit pair and sets the result bit if both bits in the pair are set. This is really useful for setting flags. Examples: 255 & 170 == 170 11111111 & 10101010 -------- 10101010 11110000 & 00001111 --------- 00000000 00111111 & 00001000 -------- 00001000 (which would be a true value) The OR operator sets the bit if one or the other is set: 32 | 64 == 96 01000000 | 00100000 --------- 01100000 10000001 | 00000111 -------- 10000111 value | 1<<n will set the nth bit from the right).The XOR operator sets the bit only if exactly one of the compared values has it set: 64 ^ 32 == 96 01000000 ^ 00100000 -------- 01100000 10000001 ^ 00000111 -------- 10000110
__________________
<insert disclaimer here> <insert shameless plug for Visual Studio here> |
|
|
|
|
|
#3 |
|
Newbie
Join Date: Apr 2008
Posts: 23
Rep Power: 0
![]() |
Re: Bitwise Operators...
Thank you so much for having such a long post O_O. Really helped me understand them ^_^.
But I have a few more questions .
|
|
|
|
|
|
#4 |
|
Caffeinated Neural Net
![]() Join Date: Jun 2005
Location: Dry west coast of Canada
Posts: 1,004
Rep Power: 5
![]() |
Re: Bitwise Operators...
Jimbo did an excellent job explaining, so I won't re-hash that, but regarding the >> operator, I believe it determines whether or not to preserve the sign bit based on the data types involved. For example:
C Syntax (Toggle Plain Text)
__________________
And once again, Probability proves itself willing to sneak into a back alley and service Drama as would a copper-piece harlot. - Vaarsuvius, Order of the Stick |
|
|
|
|
|
#5 |
|
Programming Guru
![]() Join Date: Apr 2005
Posts: 1,823
Rep Power: 5
![]() |
Re: Bitwise Operators...
It's generally not used to do math, because the fact is the difference in speed is pretty much negligible.
Take, for instance, these two programs: C Syntax (Toggle Plain Text)
C Syntax (Toggle Plain Text)
The behaviour of each program is identical, except the first shifts and the second multiplies. They both do a billion shifts or a billion multiplications in the same amount of time. This is because they are both constant time operations, and most modern compilers will do optimizations under the hood that make these differences negligible. The place where bit manipulation becomes most useful is in algorithm design, where it becomes valuable to convert a state or vertex into a distinct value for hashing and traversing. For example, say we are keeping track of a row of 8 coins, that are either heads or tails. Coin: 1 2 3 4 5 6 7 8 Face: Tails Tails Heads Tails Heads Tails Heads Heads If 1 is heads, and 0 is tails, then this can be easily represented by a number: 00101011That is the number 43 (32+8+2+1). So you might be wondering how we actually get the number 43 from an array of heads and tails. It can be done by reading each face, while setting and shifting the appropriate bits with bitwise operators. C Syntax (Toggle Plain Text)
Bitwise operators also give us the following operations on our set of coins:
Now, on the spot, I'm going to try make up a programming problem that would require all of this together... hmmm... okay. Here goes: Rob is playing Amy in a game of "Coins". "Coins" is a popular game played with 8 pennies, lined up in a row, initially in the configuration:
HTHTHTHT
Players alternate turns making 1 of 4 possible moves:
1) Remove the left coin and place it as heads on the right.
2) Remove the right coin and place it as tails on the left.
3) Flip every coin, then set the right-most coin to heads.
4) Flip any one coin.
The game ends after the 6th turn (3 complete alternations). The goal of the game for the first player is to get as many heads as possible, and for the second player to get as many tails as possible.
The winner is the player with the most of his/her own type. In the event of a tie, the first player wins by default.
In this problem, Rob always starts first and the game ends after Amy's third turn.
------------------------------------------------------------
Input:
An integer t, followed by a string of 8 characters of either 'H' or 'T'.
Output:
A name, either "Rob" or "Amy", representing who will win, given that each player plays perfectly on the t'th turn with the given configuration.
Note:
In random play, the first player is more likely to win than the second player. But in perfect play, the second player will win if he/she has the perfect strategy.
------------------------------------------------------------
Sample Input #1
1
HTHTHTHT
Sample Output #1
Amy
Sample Input #2
1
THTHTHTH
Sample Output #2
Rob
Sample Input #3
2
HHHTTHTT
Sample Output #3
Rob
Sample Input #4
5
HHHHHHHH
Sample Output #4
AmyIf you know how to write a recursive function, and want to try this out, it should be a great excercise in the advantage of bitwise operators. Here's my solution. Note that it uses every available bitwise operator. Also note that without converting the sequence of coins into an integer, we could not use a cache where the coin setup is an index into the array. Convenient! #include <stdio.h>
#define MAX (1<<8)
#define NIL -1
char cache[MAX][8];
char minimax(int coins, int turn) {
// Accepts configuration of coins, and current turn.
// Returns the person who wins (0 for Rob, 1 for Amy).
int i, j;
int tempcoins, isamy;
if(cache[coins][turn] != NIL) return cache[coins][turn];
if(turn == 7) {
// Game over; Calculate winner
for(i=0, j=0; i<8; i++)
j += (coins & (1 << i)) != 0;
return cache[coins][turn] = (j < 4);
}
isamy = (turn-1)%2;
// Move #1 - Remove the left coin and place it as heads on the right.
if(minimax(((coins << 1) & 0xFF) | 1, turn+1) == isamy)
return cache[coins][turn] = isamy;
// Move #2 - Remove the right coin and place it as tails on the left.
tempcoins = coins >> 1;
if(tempcoins & (1 << 7)) tempcoins ^= (1 << 7);
if(minimax(tempcoins, turn+1) == isamy)
return cache[coins][turn] = isamy;
// Move #3 - Flip every coin, then set the right-most coin to heads
if(minimax(~coins & 0xFF | 1, turn+1) == isamy)
return cache[coins][turn] = isamy;
// Move #4 - Flip any one coin
for(i=0; i<8; i++)
if(minimax(coins ^ (1 << i), turn+1) == isamy)
return cache[coins][turn] = isamy;
return cache[coins][turn] = !isamy;
}
int main() {
int i, t, h;
char coins[10];
scanf("%d %s", &t, coins);
for(h=0, i=0; i<8; i++)
if(coins[i] == 'H')
h |= (1 << (7-i));
memset(cache, NIL, sizeof(cache));
printf("%s\n", minimax(h, t) ? "Amy" : "Rob");
return 0;
}So, in conclusion, bitwise operators aren't generally used to do math. They should be used just as they were intended: to manipulate and access individual bits, in order to accomplish something more easily and efficiently. Trying to solve this problem without bitwise operators would be extremely painful (and inefficient)!
__________________
Waterloo's Canadian Computing Competition (CCC) - Stage 2 Problems, Solutions, and Test Data Last edited by Sane; Apr 27th, 2008 at 2:34 PM. |
|
|
|
|
|
#6 | |
|
Battle Programmer
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 751
Rep Power: 3
![]() |
Re: Bitwise Operators...
Quote:
__________________
<insert disclaimer here> <insert shameless plug for Visual Studio here> |
|
|
|
|
|
|
#7 | |
|
Programming Guru
![]() Join Date: Apr 2005
Posts: 1,823
Rep Power: 5
![]() |
Re: Bitwise Operators...
It's relatively constant. For 4 byte integers, it is regarded as constant time, as a result of the CPU's cache and the relative number of cycles required.
From my algorithm's textbook: Quote:
|
|
|
|
|
|
|
#8 | |
|
Programming Guru
![]() Join Date: Jun 2005
Location: Adelaide, South Australia
Posts: 1,206
Rep Power: 5
![]() |
Re: Bitwise Operators...
Quote:
The relative performance of operations (eg multiply by two vs a bit shift) actually depends on the machine your program will run on (eg the instruction set). The majority of good quality, modern, compilers will pick the operation that works best, depending on optimisation settings (eg compiling for speed, compiling for minimum executable file size, etc). Unless you're writing your own optimising compiler, you are writing highly critical code in assembler, or you have encountered a compiler bug there is usually no need to worry about such things. |
|
|
|
|
|
|
#9 |
|
Hmmmm ... Is there more??
Join Date: Apr 2008
Location: Post Falls, ID
Posts: 15
Rep Power: 0
![]() |
Re: Bitwise Operators...
My job often requires that I take the data created by someone else's program - and extract the parts I need into something we can use.
When extracting useful data from various binary files - I often have to use the AND operator ... A common use of bit-wise math is encoding several flags into a single byte. Suppose the program needed to store these 8 YES/NO flags: IsPatient_YN IsDoctor_YN IsHealthPlan_YN HasID_YN HasPhone_YN HasFax_YN IsActive_YN IsDeleted_YN This could be stored as a series of single-byte entries - each entry using the single character "Y" or "N". However, using bit-wise operators - the program could store all 8 of these flags in a single byte... VB Syntax (Toggle Plain Text)
VB Syntax (Toggle Plain Text)
(This is a small savings - and in these days with large storage devices - some would argue that the space saved is not worth the extra work. But if you're writing a program that deals with millions of individual records - this can be a significant savings...) A similar algorithm is (was) used in the original DOS directory entries ... the 'archive-bit' was set on a directory entry in certain circumstances. The other bits in that byte controlled the 'read-only' flag - the 'system-file' flag, etc.
__________________
Ken - New to PFO ... but been dabbling in various versions of BASIC since highschool - circa 1973. "Shouldn't the 'Air and Space' museum be empty?" - Dennis Miller |
|
|
|
|
|
#10 |
|
Newbie
Join Date: Apr 2008
Posts: 23
Rep Power: 0
![]() |
Re: Bitwise Operators...
Hey, I have been reading through all of the replies and thanks much for all the time you have put into this ^_^. I'm still pretty confused, but that is just because I haven't fully read through them yet
. 2 Quick Questions for now since they are on my mind ![]()
|
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Interesting Bitwise tricks | Wizard1988 | Coder's Corner Lounge | 9 | Nov 25th, 2007 7:09 PM |
| Bitwise Operator Question | grimpirate | PHP | 1 | Nov 13th, 2006 2:39 AM |
| Boolean operators?????? | SpaderS | C++ | 4 | Mar 20th, 2006 8:24 PM |
| bitwise operators and type double | ionexchange | C++ | 14 | Feb 12th, 2006 9:27 AM |
| need help with bitwise operations | metsfan | C | 17 | Feb 2nd, 2006 6:09 PM |