LoginSignup
0
0

More than 3 years have passed since last update.

Bashだけで10進数からn進数(2~64進数)に変換する

Last updated at Posted at 2020-10-09

はじめに

10進数からn進数(2~64進数)に変換するBashスクリプトの関数です。今回は引数チェックも入れました。Bash 4.4.12で動作を確認しています。
参考記事→Bashだけで16進数・10進数・2進数間の相互変換を行う

コード

conv_digit.sh
# Usage: conv_digit 17 2 # -> 10001
# Usage: conv_digit 31 16 # -> 1f
function conv_digit()
{
  local natural digit quotient surplus sign c64 result
  c64='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_'
  [[ ! $1 ]] && return
  if [[ ! $1 =~ ^[+\-]?[0-9]+$ ]]
  then
    echo "${FUNCNAME[0]}($1,$2): Arg 1 is invalid. call from ${FUNCNAME[1]}():${BASH_LINENO[0]}">&2
    return -1
  fi
  [[ $1 -lt 0 ]] && { natural=-$1;sign=-; } || natural=$1
  if [[ $2 ]]
  then
    if [[ ! $2 =~ ^[0-9]+$ || $2 -lt 2 || $2 -gt 64 ]]
    then
      echo "${FUNCNAME[0]}($1,$2): Arg 2 is invalid. call from ${FUNCNAME[1]}():${BASH_LINENO[0]}">&2
      return -1
    else
      digit=$2
    fi
  else
    digit=10
  fi
  echo -n $sign
  while :
  do
    surplus=$(($natural%$digit))
    natural=$(($natural/$digit))
    result=${c64:$surplus:1}$result
    [[ $natural -eq 0 ]] && break
  done
  echo $result
}

使い方

$ conv_digit 17 2
10001
$ conv_digit 31 16
1f
$ conv_digit 31
31

n進数から10進数にするにはBashの組み込み機能で行なえます。

$ echo $((16#1f))
31
$ echo $((16#$(conv_digit 31 16)))
31

補足

第一引数は変換する10進数自然数のつもりでしたが、先頭に0がつく数字は8進数として、先頭にマイナス記号(-)がつく数字は負の数として認識されるようですが、完全には動作を確認していません。小数は扱えません。
なお第二引数は進数を指定します。2から64の整数のみを指定でき、負の値や小数はエラーになります。指定しない場合は10として扱われます。

諸注意

コードはご自由に使って頂いて構いませんが、一切の保証はいたしません。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0