Permalink
Browse files

Added BitTwiddler

  • Loading branch information...
1 parent 8bd1c6c commit 10c0aa748c912841a35f10c6867bbc62f7a45ed8 @Dolkar committed Feb 2, 2012
Showing with 1,004 additions and 0 deletions.
  1. +173 −0 bit_twiddler/README.txt
  2. +726 −0 bit_twiddler/bit_twiddler.py
  3. +105 −0 bit_twiddler/unit_test.py
@@ -0,0 +1,173 @@
+Created: 1.2.2012
+Version: 1e-10a
+Author: Dolkar
+License: None
+
+An advanced interactive binary calculator made for learning purposes. Binary not
+in the sense of using only a base of two, but that it doesn't hide the actual
+integer implementation in memory. Which means, for example, that all values
+are basically unsigned integers of given width and there are no floats.
+
+The goal was to be able to implement most of bit twiddling hacks shown at
+http://graphics.stanford.edu/~seander/bithacks.html - hence the name "BitTwiddler".
+
+
+
+ Format setting
+
+First, before computing anything, you must know in what format you are
+working in - the base and bit width of values. That is quite easy to figure out
+as it is shown in the command prompt in this format: "<base><bit_width>".
+So, for example, if you see this prompt: "bin8> ", you are working with
+binary numbers with width of 8, which is the default by the way. You can change
+the working format by typing the format you want - to get 32-bit integers in
+decimal, just write "dec32".
+
+Values are printed out using the current base and are padded with that many
+zeros as needed for the current bit-width (except of decimals). You can also
+write values of the current base without base prefix ('0b' for binary,
+'0d' for decimals, '0o' for octal and '0x' for hex), although it's not
+forbidden to do so. Note that you still have to write the prefix in hex base,
+simply because the parser doesn't know if you mean a variable name or a value
+by typing 'facb'.
+
+All inputted and computed values are trimmed down to the current bit width.
+
+Apart from that, you can use a format setting to convert the result of an
+expression to the specified format regardless of the current one by
+"<format_setting><expression>"
+
+example:
+ bin8> 1000
+ 00001000
+ bin8> dec16
+ dec16> 1000
+ 1000
+ dec16> 0b1000
+ 8
+ dec16> bin8 42
+ 00101010
+
+
+
+ Expressions
+
+Nothing unusual here... You use infix notation to put together your expression
+together with parentheses as a grouper. <varname> = <expression> for assignment.
+
+If you don't assign to anything, you will get a nice output showing how exactly
+the result got computed:
+
+ bin8> 0d27 & (1 << 11) - 1
+ 00000001
+ 00000011
+ << =
+ 00001000
+
+ 00001000
+ 00000001
+ - =
+ 00000111
+
+ 00011011
+ 00000111
+ & =
+ 00000011
+
+ bin8>
+
+
+
+ Important keywords and available operators
+
+Keywords:
+'quit': Do not use this... ever!
+'maxval': Shows the maximum value which is representable with current bit width.
+ maxval + 1 = 0
+'_': Represents the last computed value.
+
+Operators:
+I hope I don't have to explain the obvious ones:
+(+, -, *, /, **, % (mod), & (and), | (or), ^ (xor), << (lshift), >> (rshift))
+You can use both ways (symbolic and named) as the operator:
+"1 | 0" is equivalent to "1 or 0".
+
+The less obvious operators:
+~ (neg): Inverts all zeros and ones in a value ("~ 0100" becomes "1011")
+rand: Returns a random value between zero and maxval (inclusive)
+lookup: Basic function for working with tables (see below)
+ "table lookup 4" is equivalent to "table[4]"
+len: Returns the length of a table
+
+
+
+ Number patterns
+
+You might often want to compute with a specific binary pattern,
+like "01010101"... But it's not so easy with dynamic bit width. That's when
+number patterns come. Any number encapsulated by curly brackets represents
+a value with an infinitely repeating binary pattern of that number.
+You can't make patterns from decimal values - it wouldn't make much sense.
+
+ bin8> {01}
+ 01010101
+ bin8> bin16
+ bin16> {01}
+ 0101010101010101
+ bin16> {0x5}
+ 0101010101010101
+ bin16> {0x0f}
+ 0000111100001111
+ bin16> hex32
+ hex32> {0x00ff}
+ 00ff00ff
+ hex32>
+
+
+
+ Lookup tables
+
+A sequence of values used for mapping numbers. You can define them as:
+"[<val1>, <val2>, <val3>, ...]" The commas are not required, but recommended.
+You can map a value by "table[<index>]", returning a value at the given index.
+Indexing starts with zero.
+
+You can use tables as operands in the same way as numbers. The operations
+are applied to all values it contains: "table + 1" increments all values
+it cantains with one. You can also operate with tables of the same length,
+where each value is mapped to it's counterpart in the other table.
+
+ bin8> table = [101, 10, 1110, 0, 11111]
+ bin8> table[10]
+ [00000101, 00000010, 00001110, 00000000, 00011111]
+ 00000010
+ lookup =
+ 00001110
+
+ bin8> len table
+ [00000101, 00000010, 00001110, 00000000, 00011111]
+ len =
+ 00000101
+
+ bin8> table + 1
+ [00000101, 00000010, 00001110, 00000000, 00011111]
+ 00000001
+ + =
+ [00000110, 00000011, 00001111, 00000001, 00100000]
+
+ bin8> table + _
+ [00000101, 00000010, 00001110, 00000000, 00011111]
+ [00000110, 00000011, 00001111, 00000001, 00100000]
+ + =
+ [00001011, 00000101, 00011101, 00000001, 00111111]
+
+
+
+ Future plans
+
+I wanted to implement custom operators in this first release, but I decided
+to leave it for later. My other plans include support for scripts and "modules",
+conditions, ternary operators and maybe, one day, in a very distant future,
+the BitTwiddler might evolve into a full language.
+
+I'm actually kind of curious if anyone will find use in this anyways...
Oops, something went wrong.

0 comments on commit 10c0aa7

Please sign in to comment.