Converting numbers on Linux among decimal, hexadecimal, octal, and binary


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.

Copyright © 2022 IDG Communications, Inc.



Source link