我一直在使用非常基本的,大部分直接的方法将基数为10的数字{1..256}
转换为基数为4或四进制数。我一直在使用简单的除法$(($NUM/4))
得到主要结果,以便得到余数$(($NUM%4))
,然后反向打印余数以得到结果。我使用以下bash
脚本来执行此操作:
#!/bin/bash
NUM="$1"
main() {
local EXP1=$(($NUM/4))
local REM1=$(($NUM%4))
local EXP2=$(($EXP1/4))
local REM2=$(($EXP1%4))
local EXP3=$(($EXP2/4))
local REM3=$(($EXP2%4))
local EXP4=$(($EXP3/4))
local REM4=$(($EXP3%4))
echo "
$EXP1 remainder $REM1
$EXP2 remainder $REM2
$EXP3 remainder $REM3
$EXP4 remainder $REM4
Answer: $REM4$REM3$REM2$REM1
"
}
main
此脚本适用于数字0-255或1-256。但是超出这个(这些)范围,结果变得混杂并经常重复或不准确。这不是一个很大的问题,因为我不打算将数字转换为256或小于0(负数[尚])。
我的问题是:"是否有更简化的方法可以使用expr
或bc
?
答案 0 :(得分:2)
$ echo {a..c}
a b c
$ echo {a..c}{r..s}
ar as br bs cr cs
$ echo {0..3}{0..3}
00 01 02 03 10 11 12 13 20 21 22 23 30 31 32 33
等等,对于0-255十进制到base-4
$ base4=({0..3}{0..3}{0..3}{0..3})
$ echo "${base4[34]}"
0202
$ echo "${base4[255]}"
3333
答案 1 :(得分:2)
int2b4() {
local val out num ret=\\n;
for ((val=$1;val;val/=4)){
out=$((val%4))$out;
}
printf ${2+-v} $2 %s${ret[${2+1}]} $out
}
仅使用1个参数调用,这将转换为 base 4 并打印结果,后跟换行符。如果存在第二个参数,则将填充此名称的变量,不打印。
int2b4 135
2013
int2b4 12345678
233012011032
int2b4 5432 var
echo $var
1110320
主要部分是(可写):
out=""
for (( val=$1 ; val > 0 ; val = val / 4 )) ;do
out="$((val%4))$out"
done
我们很容易理解转换循环(我希望)
local
确保out val num
为本地空变量并在本地初始化ret='\n'
printf
行使用一些bashisms
${2+-v}
为空,则$2
为空,如果不为则代表-v
。${ret[${2+1}]}
分别成为${ret[]}
(或${ret[0]}
)和${ret[1]}
所以这一行成了
printf "%s\n" $out
如果没有第二个参数($ 2)和
printf -v var "%s" $out
如果第二个参数是var
(请注意,没有换行符附加到填充变量,但是为终端打印添加了换行符。)
有一个 bashism 让你可以用bash下的任意基数进行计算:
echo $[4#$var]
5432
echo $[4#1110320]
5432
for integer in {1234..1248};do
int2b4 $integer quaternary;
backint=$[4#$quaternary];
echo $integer $quaternary $backint;
done
1234 103102 1234
1235 103103 1235
1236 103110 1236
1237 103111 1237
1238 103112 1238
1239 103113 1239
1240 103120 1240
1241 103121 1241
1242 103122 1242
1243 103123 1243
1244 103130 1244
1245 103131 1245
1246 103132 1246
1247 103133 1247
1248 103200 1248