Как преобразовать шестнадцатеричное в десятичное в bash / scripting, используя только функции - PullRequest
0 голосов
/ 02 июля 2018

Привет! Я очень новичок в программировании на Bash. Для задания мне поручено преобразование всех базовых типов во все остальные (по одному преобразованию за раз). Пример: десятичное в двоичное, двоичное в десятичное, шестнадцатеричное в бинарный и обратно и т. д. ... подвох в том, что нам не разрешается использовать какие-либо хитрости или ярлыки, такие как bc, poisix или любые другие решения oneliner ... даже printf запрещен. нам нужно использовать наши собственные функции, как здесь, я сделал для двоичного до десятичного

for (( x=0; num>0; x++ )); do
  em=$(echo $(( $num % 2 )))#divides num in 2 remainder gets stored in rem, num #keeps the same value
  num=$(( $num/2))#num gets divided by two and stores its new value
  array[x]=$rem
done

#printing part
if [ $x=0 ]; then #dont know why it doesnt work if i take this "if" out.
  for (( x=${#array[@]}-1; x>=0; x-- )); do #prints all remainders backwards
    echo "${array[x]"
  done
fi

так что, надеюсь, теперь вы понимаете, что я подразумеваю под "без ярлыков или уловок" .. так вот актуальная проблема, с которой я сталкиваюсь сейчас .. Вы видите, что в этом преобразовании значение num было введено пользователем через: read num но теперь мне нужно преобразовать шестнадцатеричное в десятичное значение. Я не уверен, использовать ли массив или что-то еще, что я мог бы сделать, чтобы вычислять символы внутри переменной, которая содержит и цифры, и буквы, и в то же время оценивать или сравнивать их .. Я думал о попытке: if [$ {array [x]} -eq "A"]; затем Массив [х] = 10 но хорошо ... как разобрать значение, введенное следующим образом: 6C3 и сохранить каждый символ отдельно в массиве, сохранив его значение и сравнив его / выполнив операции. спасибо за любую помощь.

1 Ответ

0 голосов
/ 02 июля 2018

Мне всегда говорили, что вы должны преобразовать число из одной базы в другую, преобразовав одну цифру сзади в этом числе, а затем умножить это число на основание и положение, в котором оно находится.

Сначала я написал функцию для преобразования одной цифры из шестнадцатеричного в десятичное. Затем я преобразую число из самой значимой цифры (от цифры слева) в dec, затем умножу на 16, затем добавлю следующую цифру, затем умножу на 16 и т. Д.

hextodec1() {
        case "$1" in
        [0-9]) echo "$1"; ;;
        a|A) echo 10; ;;
        b|B) echo 11; ;;
        c|C) echo 12; ;;
        d|D) echo 13; ;;
        e|E) echo 14; ;;
        f|F) echo 15; ;;
        esac
}

out=0
for ((i = ${#num} - 1; i >= 0; --i)); do
        ((out = out * 16 + $(hextodec1 ${num:$i:1}) ))
done
echo $out

Вы можете извлечь подстроку строки, используя ${variable_name:$start_position:$length}.
Но на самом деле самый простой способ сделать это:

echo $((0x$num))

Ваш алгоритм нуждается в некотором исправлении, потому что bash понимает десятичные числа по умолчанию или шестнадцатеричные числа, если им присвоено 0x. Таким образом, цикл for (( x=0; num>0; x++ )); do не будет работать для num=6C3, поскольку num - это строка, а bash не может сравнить число x со строкой 6C3. Вы можете сделать for ((x=0;(0x$num)>0;++x)); do, но тогда вам лучше всего просто echo $((0x$num)), потому что в первый раз вы num=$(( (0x$num) % 2 )) будете преобразовывать его в десятичное число, а в следующий раз, когда bash входит в условие цикла, переменная будет в десятичном, а не шестнадцатеричном виде.

...