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.
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
See http://docstore.mik.ua/orelly/unix/upt/ch49_03.htm
When you set ibase
or obase
, it's expressed with the current base of ibase
. So set obase
before you set ibase
if you want to express obase
in decimal.
See also http://www.gnu.org/software/bc/manual/html_mono/bc.html#SEC9
Input numbers may contain the characters 0-9 and A-F. (Note: They must be capitals. Lower case letters are variable names.) Single digit numbers always have the value of the digit regardless of the value of ibase. (i.e. A = 10.) For multi-digit numbers, bc changes all input digits greater or equal to ibase to the value of ibase-1. This makes the number FFF always be the largest 3 digit number of the input base.
So for obase=16
in ibase=6
, the 6
becomes a 5
, and it is equivalent to an output base of decimal 6 * 1 + 1 * 5 == 11
, thus:
$ echo "obase=11;ibase=6;512" | bc
161
Slightly modify the code (two ways) and your expected results appear:
for ib in {6,8,10,16}; do
echo $ib; for ob in {10,16}; do
echo -en $ib $ob" \t => " ;
ob=`echo "obase=$ib;$ob" | bc`
echo "ibase=$ib;obase=$ob;333" | bc ;
done;
done;
for ib in {6,8,10,16}; do
echo $ib; for ob in {10,16}; do
echo -en $ib $ob" \t => " ;
echo "obase=$ob;ibase=$ib;333" | bc ;
done;
done;
execute in bash sandbox
results for both ways are:
6
6 10 => 129
6 16 => 81
8
8 10 => 219
8 16 => DB
10
10 10 => 333
10 16 => 14D
16
16 10 => 819
16 16 => 333