Bitwise operators
Monkey Forums/Monkey Programming/Bitwise operators
| ||
I'm going to really show myself up here a bit, but.... I don't use bitwise operators. I understand them, but what I don't understand is how they are considered useful? Can anyone give me some game development related examples of where they are useful? |
| ||
The example below is probably one of the more common uses.Const OPTION_1:= 1 Const OPTION_2:= 2 Const OPTION_3:= 4 Const OPTION_4:= 8 Const OPTION_5:= 16 Const OPTION_6:= 32 Function DoSomething:Void(options:Int) If options & OPTION_1 'do option 1 Print "Option 1" EndIf If options & OPTION_2 'do option 2 Print "Option 2" EndIf If options & OPTION_3 'do option 3 Print "Option 3" EndIf If options & OPTION_4 'do option 4 Print "Option 4" EndIf If options & OPTION_5 'do option 5 Print "Option 5" EndIf If options & OPTION_6 'do option 6 Print "Option 6" EndIf End Function Main:Int() DoSomething(OPTION_1 | OPTION_3 | OPTION_6) Return 0 End If you are storing stuff in a database or sending over a network this is very useful. You can pack a lot of options into one integer instead of 1 byte per option. It's good in object initialization as you can create a generic object create api with a single options or style param. Each object class can then decide how to interpret the options to create an object. |
| ||
Well one example is to use them for game flags in stead of using bool data types (saves some memory as bool would be 4 bytes in size). Use an int data type and use bitwise OR to set an individual bit and then use a bitwise AND to see if it's set. You could then do something like use individual bits of a int as a method to determine what direction a player is to move when a button or key has been pressed just by setting it and then checking for it in your programme loop. You can also use bitwise data for compressing your game level data. Just like it was done on the old 8bit computers where memory was tight. See here for how Alien 8 for the ZX Spectrum was done. The bit wise shift functions can be used as a fast method for multiplication/division. If you do a bit of googling you should find plenty of examples for other uses. Read through skids code here for a another. |
| ||
Thanks you two :D That data packer looks like it could be useful for level file downloading too :) |
| ||
They can be useful for fast AI algorithms as well. For example, most professional chess programs use 'bitfields' for representing board positions. Like with the flags, the object is to get the most value out of an int, and you have the ability to use logical operations which can operate on 32/64 bits at once. You can have examples of this with the flags, as well. If you had a series of Bools storing flags to mean different things, then if you wanted to know if conditions 1, 4 and 5 are true you have to do three tests. But if they are packed into a single int as bits, you can do all sorts of such tests in one or two operations. Flags 0..9 = 1, 2, 4, 8, 16, 32, 64, 128, 256. 512 Say I have an int with all these flags set or unset. I want to know if at least one of flags 1, 2 and 4 (values 2, 4, 16) is set. All I need to do is say: If ( flags & 22 ) <> 0 ' At least one is set End And if I want to know if all of them are set: If ( flags & 22 ) = 22 ' All three are set End |
| ||
That data packer looks like it could be useful for level file downloading too :) Be careful when using data compressed as strings as Apple OS's don't like custom string encoding. If ( flags & 22 ) <> 0 Just to point out. You wouldn't need to add <> 0 as any condition other than zero value equates to a bool value of TRUE. So any bit "trapped" would give a value greater than zero. You would only use the equals to check if a specific bit or number of bits are set.' At least one is set End A few things to remember when dealing with binary operations. It's a lot easer representing numbers in hexadecimal format than in decimal (or any other) due to the relationship that each character ( 0-9 with A-F representing 10-15) would be bits or the sum of 4 bits (a nibble) within a byte. E.G. $FFE61216 is a lot easier to break down than 4293267990 or 11111111111001100001001000010110. And rather than trying to remember what bit(s) is is meant to do what. You could assign a constant variable to represent it. As if I remember constant variables get hard coded into your code at compile time. You could check for what bit(s) are set like so Const bit4=$10 '16 Const bit2=$04 '4 Const bit1=$02 '2 If (flags & (bit4|bit2|bit1)) = $16 But once your program is complete you should add the values together and change (bit4|bit2|bit1) to that added value to do a bit of optimising. |
| ||
"Just to point out. You wouldn't need to add <> 0 as any condition other than zero value equates to a bool value of TRUE. So any bit "trapped" would give a value greater than zero. You would only use the equals to check if a specific bit or number of bits are set." Yeah, I know, but I like to make it explicit. I suppose I should probably write: If Bool( flags & 22 ) ..just to make sure it gets optimised away. With the flags you can also optimise like: Const BIT1:Int = 2 Const BIT2:Int = 4 Const BIT4:Int = 16 Const MYCOMBO:Int = BIT1 | BIT2 | BIT4 |
| ||
Const MYCOMBO:Int = BIT1 | BIT2 | BIT4 Only problem with that method is giving it a meaningful name for what it does that you can remember off the top of you head. I tend to stick to a strict naming, ordering and coding method and when I'm happy I let find and replace do all the work. Yeah, I know, but I like to make it explicit. I suppose I should probably write: Yeah know what you mean. But sometimes I find it just too much hard work typing those extra keywords.If Bool( flags & 22 ) ..just to make sure it gets optimised away. Edit: @RAZ here's a naff demo of what you could do I could think of a few ways on how to do it for a static platform game (think Manic Miner/Jet Set Willy) Here's the home page to some of the data formats for old ZX Spectrum games to give you some ideas. |
| ||
Base 64 encoding. I created my own functions to do that, before realizing it was a very common thing and even had a name. like, in binary (a byte is made of 8 bits): 11100000, 10001000, 10101010 this would become in base 64: 111000, 001000, 100010, 101010 With that you can choose an ASCII character to represent those. Pro: Copy-pastable anywhere you want URL safe Con: 33% larger (4 characters to represent 3 bytes) A little processing is needed to pack/unpack data I use it to save, pack, transfer data without fear a character would cause a mess. :D |
| ||
Also since I'm a big fan of game replays I also use bitwise operation to store and retrieve commands from a particular frame. This way, if you did something really awesome, you can re-watch yourself in action or share it with other people. Example: http://www.youtube.com/watch?v=l3JHfQ3c6HE That concept works pretty much like Skn3's Function "DoSomething", you pass an integer to the function, and you check which bits are set to determine which keys are being pressed during a particular frame. --- And if you like encryption you can try the xor bitwise operation too http://en.wikipedia.org/wiki/XOR_cipher |