bc and its ibase/obase options:

user unknown picture user unknown · Mar 27, 2012 · Viewed 18.6k times · Source

I stumbled over a curious bug, I think:

I tried to read "512" as a number to base 6, and output it as base 16:

echo "ibase=6;obase=16;512" | bc
161

As you can see, the output is 161, but it should be bc(sic!). I tried with base 10:

echo "ibase=6;obase=10;512" | bc
512

The value is unchanged. Curious! Default obase is 10. If I omit it:

echo "ibase=6;512" | bc
188

Well, that seems right. In a two step process, it works:

echo "obase=16;"$(echo "ibase=6;512" | bc) | bc
BC

So I made a script for different bases, but it keeps me puzzled:

for ib in {6,8,10,16}; do echo $ib; for ob in {10,16}; do echo -en $ib $ob"     \t => " ; echo "ibase=$ib;obase=$ob;333" | bc ; done; done; 
6
6 10         => 333
6 16         => 108
8
8 10         => 333
8 16         => 119
10
10 10        => 333
10 16        => 14D
16
16 10        => 333
16 16        =>  01 15 05

Shall I file a bugreport, or do I miss the obvious? I can't really believe that such a basic tool is broken.

Answer

Mat picture Mat · Mar 27, 2012

Not a bug.

As soon as ibase=6 is interpreted, numbers are read in base 6. So ibase=6;obase=16 makes obase's value to be 16base 6 which is invalid, and is interpreted as 11decimal.

From the man page:

For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1.

So 16 is interpreted as 15base 6 which is 11decimal. And the conversion is correct.

Set obase before ibase, or make sure to specify your obase in base ibase.

$ echo "obase=16;ibase=6;512" | bc
BC