bc and its ibase/obase options:

前端 未结 3 1178
眼角桃花
眼角桃花 2021-02-01 10:58

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         


        
相关标签:
3条回答
  • 2021-02-01 11:40

    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
    
    0 讨论(0)
  • 2021-02-01 11:54

    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
    
    0 讨论(0)
  • 2021-02-01 11:57

    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
    
    0 讨论(0)
提交回复
热议问题