Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

..
Failed to load latest commit information.
README.txt
bit_twiddler.py
unit_test.py

README.txt

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...
Something went wrong with that request. Please try again.