我试图制作一个小二进制数来计算二进制数。它的工作原理如下:
- 将'1'或'0'数字作为SEPARATE参数。例如“./bin2dec 1 0 0 0 1 1 1”。
- 对于每个参数数字:如果它是'1',则将其乘以相应的2的幂(在上面的情况下,最左边的'1'将是64),然后将其加到'sum'变量中
这是代码(注意到它是错误的):
#!/bin/bash
p=$((2**($#-1))) #Finds the power of two for the first parameter.
sum=0 #The sum variable, to be used for adding the powers of two in it.
for (( i=1; i<=$#; i++ )) #Counts all the way from 1, to the total number of parameters.
do
if [ $i -eq 1 ] # *THIS IS THE WRONG POINT* If parameter content equals '1'...
then
sum=$(($sum+$p)) #...add the current power of two in 'sum'.
fi
p=$(($p/2)) #Divides the power with 2, so to be used on the next parameter.
done
echo $sum #When finished show the 'sum' content, which is supposed to be the decimal equivalent.
我的问题在于注意点(第10行,包括空白行)。在那里,我试图检查EACH参数的内容是否等于1.我如何使用变量来做到这一点?
例如,$ 1是第一个参数,$ 2是第二个参数,依此类推。我希望它像$ i,其中'i'是每次增加1的变量,以便它与下一个参数匹配。
除此之外,我试过这个:'$(echo“$”$ i)'但是没有用。
我知道我的问题很复杂,我尽力让它变得清晰。 有什么帮助吗?
答案 0 :(得分:2)
这个怎么样?
#!/usr/bin/bash
res=0
while [[ $# -gt 0 ]]
do
res=$(($res * 2 + $1))
shift
done
echo $res
$ ./bin2dec 1 0 0 1
9
shift
是一个命令,它将传递给脚本的每个参数向左移动,将其值减1,这样$2
的值现在在$1
移位后。您实际上也可以使用带有移位的数字来指示移动变量的距离,因此shift
就像shift 1
,而shift 2
会给$1
使用的值在$3
。
答案 1 :(得分:1)
这个怎么样?
#!/bin/bash
p=$((2**$#))
while(($#)); do
((sum+=$1*(p/=2)))
shift
done
echo "$sum"
或者这个(向另一个方向):
#!/bin/bash
while(($#)); do
((sum=2*sum+$1))
shift
done
echo "$sum"
请注意,没有错误检查。
请考虑fedorqui的评论:使用echo $((2# binary number ))
将二进制转换为十进制。
另请注意,如果您提供过多参数,这将很容易溢出。
如果您想要不会溢出的内容,请考虑使用dc
:
dc <<< "2i101010p"
(使用2i
将输入基数设置为2,并将101010
放在堆栈上并p
将其设置为拉。)
或者,如果您更喜欢bc
:
bc <<< "ibase=2;101010"
请注意,这些需要将二进制数作为一个参数输入,而不是将所有数字分开。如果你真的需要将所有数字分开,你也可以使用这些有趣的方法:
Pure Bash。
#!/bin/bash
echo $((2#$(printf '%s' "$@")))
使用直流。
#!/bin/bash
dc <<< "2i$(printf '%s' "$@")p"
使用bc。
#!/bin/bash
bc <<< "ibase=2;$(printf '%s' "$@")"
滥用IFS,使用直流。
#!/bin/bash
( IFS=; echo "2i$*p" ) | dc
滥用IFS,使用bc。
#!/bin/bash
( IFS=; echo "ibase=2;$*" ) | bc
所以我们仍然没有回答你的问题(你对OP的评论中的问题):并找出我们是否以及如何使用变量来引用参数。它是在使用间接扩展进行Bash。您可以在Shell Parameter Expansion section of the Bash reference manual中阅读相关内容。最好的方法是在终端显示:
$ a="hello"
$ b=a
$ echo "$b"
a
$ echo "${!b}"
hello
整洁,嗯?它与位置参数类似:
$ set param1 param2 param3
$ echo "$1, $2, $3"
param1, param2, param3
$ i=2
$ echo "$i"
2
$ echo "${!i}"
param2
希望这有帮助!
答案 2 :(得分:1)
要按名称间接引用变量,请使用${!name}
:
i=2
echo "${!i} is now equivalent to $2"
答案 3 :(得分:0)
也尝试这个:
#!/bin/bash -
( IFS=''; echo $((2#$*)) )