A Really Nice Hex Calculator

Posted by Cliff Brake on 2009-01-09 | Read the First Comment

When working with embedded software, I often have a need for a hex calculator.  Over the years I’ve used a number of different tools.  Through college and for several years after, I used my HP48 calculator.  It is a great tool.  Around 1998, I discovered the Python programming language.  As Python supports an interactive session, it works well as a desktop calculator — I don’t think I have used my HP48 since I discovered Python.  Recently, I’ve been using Ruby more in place of Python and am finding it is even nicer.  This article presents several tips and snippets of code for using Ruby as a very effective hex calculator.

For those of you not familiar with Ruby, Ruby is an interpreted scripting language for quick and easy object-oriented programming — similar in concept to Python or Perl.

Ruby provides an interactive Ruby shell called “irb”.  After you install Ruby, you can run irb from a command prompt.  You can immediately do useful calculations like the following:

 irb(main):001:0> a = 10
=> 10
irb(main):002:0> b = 23
=> 23
irb(main):003:0> a+b
=> 33

Hexadecimal numbers are prefixed with “0x” as in many other languages:

 irb(main):005:0> c = 0x1000
=> 4096

It is easy to convert from hex to decimal — just type the hex number, hit return and Ruby will give you the decimal equivalent as shown above.   To convert from decimal to hex, I often just use the printf statement.  The syntax is similar to C, so it is very natural for embedded programmers.

 irb(main):006:0> printf "0x%x", (3*1024*1024)
0x300000=> nil

Ruby provides standard shift operators similar to those found in C.  For example, if you want to know the hex value when bits 15 and 23 are set high:

irb(main):019:0> printf "0x%x", (1<<15)|(1<<23)
0x808000=> nil

It is often useful to know what bits are set in a particular number when determining if a bit in a status register is high, what address bits are used, etc. Ruby provides a bit reference method in the form.


n is the nth bit in a binary number fix where fix[0] is the least significant bit.  Some examples:

irb(main):010:0> 2[0]
=> 0
irb(main):011:0> 2[1]
=> 1
 irb(main):017:0> a = 3*1024*1024
=> 3145728
irb(main):018:0> 31.downto(0) {|n| print a[n]}
00000000001100000000000000000000=> 31

For convenience, I wrote a simple module called bits.rb that extends the basic Integer number class and provides a nice display of the bits in a number.  To use this, create a file called bits.rb with the following contents and drop it in your Ruby site_ruby directory.

 M = 1024*1024
K = 1024

class Integer
        def bits
                print "3322222222221111111111n"
                print "10987654321098765432109876543210n"
                print "---|---|---|---|---|---|---|---|n"
                31.downto(0) { |x| print self[x] }

And to use this extension to see what address bits are used to decode 8MB of address space:

 irb(main):020:0> require 'bits'
=> true
irb(main):021:0> (8*M).bits
00000000100000000000000000000000=> 31

From this example, we can see that address bits 0 through 23 are required to decode 8MB of address space.


Update 2009-07-30

The following was posted as a comment to my old web site:

An even easier way of converting between bases in Ruby:

irb(main):001:0> puts 300.to_s(16)
=> nil
irb(main):002:0> puts "12c".to_i(16)
=> nil
irb(main):003:0> puts 255.to_s(2)
=> nil

Very nice!