You might not be challenged very often to convert numbers from one numbering system to another but, when you are, you can do it with either of two fairly easy commands on the Linux command line.

Converting in your head can be taxing, especially for longer numbers. While the decimal numbering system allows any digit in a number to have any of ten values (0-9), digits in hexadecimal numbers can have 16 (0-F), digits in octal numbers only eight (0-7) and digits in binary numbers only two (0-1).

And, whether you like it or not, from time to time you are likely to run into numbers displayed in hex or octal, and knowing how to convert them from one number base to another can come in handy.

To get started, the decimal numbers 5 to 16 in the four numbering systems look like this:

5 6 7 8 9 10 11 12 13 14 15 16 <== decimal

5 6 7 8 9 a b c d e f 10 <== hexadecimal 5 6 7 10 11 12 13 14 15 16 17 20 <== octal 101 110 111 1000 1001 1010 1011 1100 1101 1110 1111 10000 <== binary

## Using the **printf** command to convert decimal numbers

To convert a number from decimal to hexadecimal, you can use a **printf** command like the one below that converts decimal 15 to hexadecimal:

$ printf ‘%xn’ 15 f

To convert to octal instead, replace the “%x” (hexadecimal) with “%o” (octal):

$ printf ‘%on’ 15 17

For the 17 shown in the second example above, recall that the first digit (1) has a decimal value of 8 and the second (7) a value of 7. Therefore, the octal result is equal to decimal 15.

Turning these conversions into scripts is easy. Here are two scripts that will prompt for the number to be converted and then run the **printf** command to do the conversion for you.

#### dec2hex

#!/bin/bash echo -n “Enter a decimal number> “ read number printf ‘%xn’ $number

#### dec2oct

#!/bin/bash echo -n “Enter a decimal number> “ read number printf ‘%on’ $number

Note: The **printf** command doesn’t have an option for converting to binary.

## Using the** bc** command to convert decimal numbers

Using the **bc** (calculator) command, you can do the same type of conversions with commands like those shown below.

The first example converts the decimal number 16 to base 16 (hexadecimal). Since in hexadecimal the second digit from the right represents the 16s position (that’s the decimal 16), the 1 means decimal 16. The “obase” setting means “output base”. This is the format you want the number to be converted to. Because the “ibase” (input base) is not provided, it is assumed to be decimal.

$ echo “obase=16; 16” | bc 10

The next command converts that same number to octal. Since, in octal, the second digit from the right represents the decimal 8s position, a 2 means decimal 16 (two 8s).

$ echo “obase=8; 16” | bc 20

With the next larger number, a decimal 17, we get 21—two decimal 8s and one 1 result.

$ echo “obase=8; 17” | bc 21

The **bc** command works just as well with binary as it does with hex and octal, so we can also convert numbers to binary. Here’s the command to display decimal 16 as a binary number:

$ echo “obase=2; 16” | bc 10000

Described in base 10, that’s one 16, no 8s, no 4s, no 2s, and no 1s.

While the binary system came into use because it works directly with the on/off state of electronics, the octal and hexadecimal systems provide easy conversions so that we humans don’t have to look at long strings of 0’s and 1’s. Even this doesn’t restrict the operation of the **bc** command which has no problem working with a base 3, base 7 or any other numbering base that you might want to experiment with.

$ echo “obase=3; 16” | bc 121

Described as decimal numbers, the 121 in the above example represents one 9, two 3’s and one 1. Here’s the base 7 version:

$ echo “obase=7; 16” | bc 22

The digits above represent two decimal 7’s and two 1’s.

## Converting numbers to decimal with** bc**

With all that said, you can also use the **bc** command to turn numbers expressed in hex, octal, or binary to decimal. Just specify the **obase** (output base) value as 10, the **ibase** (input base) number as 16 if the starting number of hex, 8 if it’s octal and 2 if it’s binary as in the examples shown below.

$ echo “obase=10; ibase=16; F” | bc 15 $ echo “obase=10; ibase=8; 15” | bc 13 $ echo “obase=10; ibase=2; 112” | bc 7

As in the earlier scenario, turning these commands into scripts takes only a little effort.

#### hex2dec

#!/bin/bash echo -n “Type a hex number> “ read number echo “obase=10; ibase=16; $number” | bc

#### oct2dec

#!/bin/bash echo -n “Type a octal number> “ read number echo “obase=10; ibase=8; $number” | bc

#### bin2dec

#!/bin/bash echo -n “Type a binary number> “ read number echo “obase=10; ibase=16; $number” | bc

## Using aliases for number-base conversions

While the scripts shown above are easy to set up, probably the most convenient way to implement any of the conversions shown is to set them up as a group of aliases. Adding the alias below to your **~/.bashrc** file would make them available on your next login or as soon as you source the file (e.g., by running **. ~/.bashrc**).

# convert from decimal alias dec2hex=’f(){ echo “obase=16; ibase=10; $1” | bc; unset -f f; }; f’ alias dec2oct=’f(){ echo “obase=8; ibase=10; $1” | bc; unset -f f; }; f’ alias dec2bin=’f(){ echo “obase=2; ibase=10; $1” | bc; unset -f f; }; f’ # convert to decimal alias hex2dec=’f(){ echo “obase=10; ibase=16; $1” | bc; unset -f f; }; f’ alias oct2dec=’f(){ echo “obase=10; ibase=8; $1” | bc; unset -f f; }; f’ alias bin2dec=’f(){ echo “obase=10; ibase=2; $1” | bc; unset -f f; }; f’

Afterwards, you can run the aliases like this:

$ dec2hex 15 F $ dec2oct 15 17 $ dec2bin 15 1111 $ hex2dec F 15 $ oct2dec 17 15 $ bin2dec 1111 15

### Wrap-Up

Converting numbers from one numbering system to another can be tedious, but you can save yourself a lot of trouble using the **printf** and **bc** commands, especially if you set them up as scripts or aliases.