Bashを使用して計算を実行し、16進入力を提供すると正しく計算されますが、結果は10進数として出力されます。これは普通ですか?明らかに結果を16進数で提供するので、結果を16進数で表示したいと思います。これを変える方法はありますか?
わかりましたprintf
。しかし、printf
増分などを使用して変数を少し更新するたびにそれを呼び出すのは奇妙です。
例えば
echo $((0xa+1))
結果は11
私が予想した通りでしたb
。
答え1
$((0xa+1))
算術式の評価を10進数表現に拡張する算術拡張です0xa+1
。
0x
この式の後には、16進整数定数、2進加算演算子、および10進整数定数はa+1
続きません。0xa
+
1
私が知る限り、Bourneに似た唯一のシェルは、10以外の進数で整数算術拡張を実行でき、次の構文を使用して拡張するzsh
進数を明示的に指定する必要があります。
$ echo $(( [#16] 0xa + 1 ))
16#B
$ echo $(( [##16] 0xa + 1 ))
B
$ set -o c_bases
$ echo $(( [#16] 0xa + 1 ))
0xB
同様に、以下をksh
使用して整数変数に塩基を割り当てることができます。
$ typeset -i16 var
$ (( var = 0xa + 1 ))
$ echo "$var"
16#B
$ set -o c_bases
$ echo "$var"
0xB
(kshが16#b
そこに提供され、c_bases
オプション(オプションが設定されている場合ではなく16進数の0xBAD
代わりに提供されます)が具体的です)。16#BAD
077
8#77
octal_zeroes
zsh
また、整数算術式( 、 、 、 などの算術演算子をzsh
使用)内で変数を代入すると、整数型を取得し(真が割り当てられていない場合)、明示的な基数を持つ最も右の整数を継承します。定数の基本(たとえば、、、、)です。=
--
++
*=
-=
+=
10#12
0x12
0b11
たとえば。(( a = 0x10 + 0b1000 ))
は24の整数変数としてtypeset -gi2 a=24
定義され、2進数()に展開されます。a
$a
2#11000
info zsh 'Arithmetic Evaluation'
詳細より。
bash
kshではコピーしますtypeset -i
が、コピーしませんtypeset -i<base>
。
bash
数値を10以外の進数に変換するには、組み込みprintf
関数を使用して他の人が示すように8と16を表すか、///を使用して異なる進数(サポートされる進数の範囲とその進数の範囲)を表すことができますdc
。表現されているのは、これらの塩基の違いです))です。bc
ksh
zsh
たとえば、30進数に変換するには、次のようにします。
base30_dc() { echo "30o $1 p" | dc; }
base30_bc() { echo "obase=30; $1" | bc; }
base30_ksh93() { ksh93 -c 'printf "%..30d\n" "$@"' ksh "$@"; }
base30_zsh() { zsh -c 'echo $(([##30] $1))' zsh "$1"; }
以下を提供します。
$ base30_dc 1234
01 11 04
$ base30_bc 1234
01 11 04
$ base30_ksh93 1234
1b4
$ base30_zsh 1234
1B4
ただし、負の定数はdc
符号で表されます。_
whileは-
バイナリ減算演算子ですdc
(逆ポーランド表記)。
$ base30_dc _1234
- 01 11 04
$ base30_dc '0 1234 -'
- 01 11 04
算術式内で認識される数値型もシェルによって異なります。
123
0123
POSIXでは、10進数、8進数、16進数の定数をそれぞれ認識するには、最小限と構文が必要です0x123
。一部のシェルはデフォルトで8進数を優先またはmksh
認識zsh
しません0123
。これは、有用なものよりも頻繁に邪魔になります(たとえば、ゼロパディング番号を処理するとき)、特定のPOSIX互換モードが有効になっている場合(オプションまたはposix
)のシミュレーション。mksh
octalzeroes
sh
zsh
ksh、bash、およびzshは、12#123
すべてのベースの入力数の表現をサポートします(やはり範囲は異なります)。
2#111
zsh は 2 進数の置換で 0b111 をサポートします。_
読みやすくするために内部番号を挿入します(たとえば、1_000_000
または0xdead_beef
)。
ksh93、zsh、yashは浮動小数点数(0.123
または0,123
ロケールに応じてksh93で)、、、1e20
...をサポートします。 ksh93は、0xA.Bp-3(またはロケールに応じて0xA、Bp-3)などの16進浮動小数点表現もサポートしています。inf
nan
答え2
Bash(または実際には他のシェル)は、一般的なプログラミングに適したツールではありません。 Bashは、より複雑な演算はどこか浮動小数点演算も処理しません。殻はシェル、その中にシンプルで小さなスクリプトを書くことができますが、汎用プログラミング言語とは考えてはいけません。そうではありません。
このようなタスクを実行するためにbashを使用する必要があると主張する場合は、次に始まるより複雑な解決策を使用する必要がありますprintf
。
$ printf '%x\n' "$((0xa+1))"
b
良いニュースは、少なくとも次のことができることです。
$ printf '%x\n' 11
b
printf
したがって、1つから別のものに簡単に変換できます。つまり、毎回次を呼び出す必要はありません。
var=0xa
((var++))
echo "Var (decimal): $var"
printf 'Var (hex): %x\n' "$var"
上記のコマンドを実行すると、以下が印刷されます。
$ foo.sh
Var (decimal): 11
Var (hex): b
つまり、16進数で操作を実行でき、何かを印刷するまで表示方法を気にする必要はありません。
しかし、いいえ、シェルでこのようなことを行うための基本的な方法は見つかりません。なぜなら、シェルを設計された目的以外の目的で使用しようとしているからです。