bc и его опции ibase/obase:

Я наткнулся на любопытную ошибку, я думаю:

Я попытался прочитать "512" как число для базы 6 и вывести его как базу 16:

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

Как видите, на выходе 161, но оно должно быть bc(Так!). Я попробовал с базой 10:

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

Значение не изменяется. Любопытно! По умолчанию obase - 10. Если я его опущу:

echo "ibase=6;512" | bc
188

Ну, это кажется правильным. В два этапа это работает:

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

Поэтому я сделал скрипт для разных баз, но он меня озадачивает:

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

Должен ли я подать отчет об ошибке или я пропущу очевидное? Я не могу поверить, что такой основной инструмент сломан.

3 ответа

Решение

Не ошибка

Как только ibase=6 интерпретируется, цифры читаются в базе 6. Так ibase=6;obase=16 делает значение obase равным 16 основам6, что недопустимо и интерпретируется как 11десятичное число.

Со страницы руководства:

Для многозначных чисел bc изменяет все входные цифры, большие или равные ibase, на значение ibase-1.

Таким образом, 16 интерпретируется как 15основание 6, которое является 11десятичным. И преобразование правильное.

Задавать obase до ibase, или не забудьте указать свой obase в базе ibase,

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

Смотрите http://docstore.mik.ua/orelly/unix/upt/ch49_03.htm

Когда вы установите ibase или же obaseэто выражается с текущей базой ibase, Так установить obase прежде чем установить ibase если вы хотите выразить obase в десятичном.

Смотрите также http://www.gnu.org/software/bc/manual/html_mono/bc.html

Входные числа могут содержать символы 0-9 и AF. (Примечание: они должны быть прописными. Буквы в нижнем регистре являются именами переменных.) Однозначные числа всегда имеют значение цифры независимо от значения ibase. (т. е. A = 10.) Для многозначных чисел bc изменяет все входные цифры, большие или равные ibase, на значение ibase-1. Это делает число FFF всегда самым большим трехзначным числом входной базы.

Таким образом, для obase=16 в ibase=6, 6 становится 5, и это эквивалентно выходной базе десятичной 6 * 1 + 1 * 5 == 11, таким образом:

$ echo "obase=11;ibase=6;512" | bc
161

Немного измените код (двумя способами), и ваши ожидаемые результаты появятся:

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;

выполнить в песочнице Баш

Результаты для обоих способов:

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
Другие вопросы по тегам