在 bash 中将十进制转换为 Base-4
Convert decimal to Base-4 in bash
我一直在使用一种非常基本且大部分直接的方法将 10 进制数 {1..256}
转换为 4 进制数或四进制数。我一直在使用简单的除法 $(($NUM/4))
来获得主要结果以获得余数 $(($NUM%4))
然后反向打印余数以得出结果。我使用以下 bash
脚本来执行此操作:
#!/bin/bash
NUM=""
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(负数 [yet])的数字。
我的问题是:“是否有更简单的方法来执行此操作,可能使用 expr
或 bc
?
创建查找 table
$ 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
bash
中的 Base 4 转换
int2b4() {
local val out num ret=\n;
for ((val=;val;val/=4)){
out=$((val%4))$out;
}
printf ${2+-v} %s${ret[${2+1}]} $out
}
仅使用 1 个参数调用,这将转换为 base 4 并打印结果,后跟 newline。如果存在第二个参数,将填充此名称的变量,不打印。
int2b4 135
2013
int2b4 12345678
233012011032
int2b4 5432 var
echo $var
1110320
详细解释:
主要部分是(可以写成):
out=""
for (( val= ; val > 0 ; val = val / 4 )) ;do
out="$((val%4))$out"
done
我们的转换循环很容易理解(我希望)
local
确保out val num
为局部空变量并在局部初始化ret='\n'
printf
line use some bashisms
如果</code>为空,则<li><code>${2+-v}
为空,否则表示-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
我一直在使用一种非常基本且大部分直接的方法将 10 进制数 {1..256}
转换为 4 进制数或四进制数。我一直在使用简单的除法 $(($NUM/4))
来获得主要结果以获得余数 $(($NUM%4))
然后反向打印余数以得出结果。我使用以下 bash
脚本来执行此操作:
#!/bin/bash
NUM=""
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(负数 [yet])的数字。
我的问题是:“是否有更简单的方法来执行此操作,可能使用 expr
或 bc
?
$ 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
bash
中的 Base 4 转换int2b4() {
local val out num ret=\n;
for ((val=;val;val/=4)){
out=$((val%4))$out;
}
printf ${2+-v} %s${ret[${2+1}]} $out
}
仅使用 1 个参数调用,这将转换为 base 4 并打印结果,后跟 newline。如果存在第二个参数,将填充此名称的变量,不打印。
int2b4 135
2013
int2b4 12345678
233012011032
int2b4 5432 var
echo $var
1110320
详细解释:
主要部分是(可以写成):
out="" for (( val= ; val > 0 ; val = val / 4 )) ;do out="$((val%4))$out" done
我们的转换循环很容易理解(我希望)
local
确保out val num
为局部空变量并在局部初始化ret='\n'
printf
line use some bashisms-
如果
</code>为空,则<li><code>${2+-v}
为空,否则表示-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