More bc weirdness

As I mentioned in a footnote to my previous post, I just discovered that variable names in the bc programming language cannot contain capital letters. I think I understand why: Capital letters are reserved for hexadecimal constants, though in a weird sort of way.

At first variable names in bc could only be one letter long. (This is still the case in the POSIX version of bc but not in Gnu bc.) And since A through F were reserved, you might as well make things simple and just reserve all capital letters. Maybe that was the thinking.

If you enter A at the bc prompt, you get back 10. Enter B you get 11, etc. So bc assumes a number containing a hex character is a hex number, right? Actually no. It assumes that any single letter that could be a hex number is one. But in numbers with multiple digits, it interprets letters as 9’s. Yes, 9’s.

The full story is a little more complicated. bc will work in multiple bases, and it lets you set the input and output bases with the variables ibase and obase respectively. Both are set to 10 by default. When a number contains multiple characters, letters less than ibase are interpreted as you’d expect. But letters greater than or equal to ibase are interpreted as ibase – 1.

So in base 12 in a number represented by more than one character, A means 10 and B means 11. But C, D, E, and F also mean 11. For example, A0 is 120 and BB is 143. But CC is also 143.

If ibase is set to 10, then the expression E == F evaluates to false, because 14 does not equal 15. But the expression EE == FF evaluates to true, because 99 equals 99.

If you set ibase to 16, then you’re in hex mode and the letters A through F behave exactly as expected.

If you want to go back to base 10, you need to set ibase to A, not 10. If you’re in hex mode, every number you enter is interpreted in hex, and so “10” is interpreted as the number we usually write as 16. In any base, setting ibase to 10 does nothing because it sets the base equal to the base.

3 thoughts on “More bc weirdness

  1. One thing that this post reminded me of is that no matter what base we’re in, the correct answer to “What base are we in?” is “10”.

    So if you’re not sure of what the current base is, you could figure it out by asking what “10 – 1” is. Unfortunately, this assumes that ibase == obase. I wonder if there’s a way to figure it out without that assumption.

  2. to avoid weird ibase/obase confusion, I always try to specify as addition
    ibase=16;
    obase=9+1;
    ibase=1+1+1+1+1+1;

Comments are closed.