Fancy Tricks for Changing Numeric Base
In this article, I'm covering something that's a little abstruse: converting numeric bases within shell scripts. There are really four commonly used numeric bases to consider: binary, octal, decimal and hexadecimal. You're used to working in base-10, so 10 = 1 * 10**1 + 0 and 100 = 1 * 10**2 + 0 * 10**1 + 0.
That maps to other numeric bases, so 1010 base-2 or binary is really 1 * 2**3 + 0 * 2**2 + 1 * 2**1 + 0 or 8 + 0 + 2 + 0 = 10 decimal. Octal is the same thing, so 33 base-8 converts to decimal as 3 * 8**1 + 3 = 27.
Hexadecimal presents a different challenge because a base-16 numbering system doesn't fit neatly into our Arabic numerals 0, 1, 2, ... 9. "Hex", as it's known informally, adds A, B, C, D, E and F, so that the decimal value 10 is represented in Hex as "A". That's where the math gets interesting, so 33 base-16 = 3 * 16**1 + 3 = 48 + 3 = 51.
The long, complicated way to create a base conversion utility is therefore to disassemble every value given and apply the translation shown, then have an internal value that's a common base (probably base-10), then have another routine that converts the common base to the desired output base.
There are smarter ways to do this, as I'll discuss, but for now,
let's look at the
bc command, which supports users specifying both
the input and output numeric bases.
bc, the binary calculator, is a bit
tricky to work with as it's an old-school UNIX command. As I discuss
at length in my book Wicked Cool Shell Scripts, the most common way to
work with the crude but interactive
bc program is
echo to send
it the commands needed, as demonstrated here:
$ echo '333 * 0.35' | bc 116.55
Useful (particularly since
)) can't work with floats and
decimal values), but where this gets really interesting is with those
input and output numeric bases.
Let's say I want to confirm a conversion I listed earlier, by converting 33 hex into decimal. This is easily done:
$ echo 'ibase=16; 33' | bc 51
That's simple. Now, let's do something bigger and more complicated:
$ echo 'ibase=16; FEF33D9' | bc 267334617
ibase is the input numeric base. The output base is specified as
obase. And that's it—easy enough!
So let's take the same hex value as input but force the output to octal instead of the default decimal:
$ echo 'ibase=16; obase=8; FEF33D9' | bc 1773631731
Would you rather work in binary? You can do that too:
$ echo 'ibase=16; obase=2; FEF33D9' | bc 1111111011110011001111011001
That's a lot of ones and zeroes, for sure. It makes me think of Interstellar, but that's another article entirely!
Dave Taylor has been hacking shell scripts for over thirty years. Really. He's the author of the popular "Wicked Cool Shell Scripts" and can be found on Twitter as @DaveTaylor and more generally at www.DaveTaylorOnline.com.
|Chemistry on the Desktop||Mar 23, 2017|
|Five HPC Cost Considerations to Maximize ROI||Mar 23, 2017|
|Two Ways GDPR Will Change Your Data Storage Solution||Mar 22, 2017|
|Android Candy: That App Is for the Birds!||Mar 22, 2017|
|Hodge Podge||Mar 21, 2017|
|William Rothwell and Nick Garner's Certified Ethical Hacker Complete Video Course (Pearson IT Certification)||Mar 20, 2017|
- Chemistry on the Desktop
- Five HPC Cost Considerations to Maximize ROI
- Preseeding Full Disk Encryption
- Hodge Podge
- William Rothwell and Nick Garner's Certified Ethical Hacker Complete Video Course (Pearson IT Certification)
- Two Ways GDPR Will Change Your Data Storage Solution
- Two Factors Are Better Than One
- GRUB Boot from ISO
- Minifree Ltd.'s GNU+Linux Computers
- Flash ROMs with a Raspberry Pi