![因尝试在 Bash 数组中使用十进制值而陷入困境](https://linux22.com/image/216530/%E5%9B%A0%E5%B0%9D%E8%AF%95%E5%9C%A8%20Bash%20%E6%95%B0%E7%BB%84%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%8D%81%E8%BF%9B%E5%88%B6%E5%80%BC%E8%80%8C%E9%99%B7%E5%85%A5%E5%9B%B0%E5%A2%83.png)
这是一些简单的测试代码。
#!bin/bash
cpm=(0 1 0.094)
lv=1
attack=5
defense=9
stamina=16
echo $((cpm[lv]))
mycpm=$((cpm[lv]))
#mycpm=`echo "0.094" | bc -l`
cq=`echo "$attack*$defense*1/10*sqrt($stamina)*2^2*$mycpm" | bc -l`
echo $cq
终端输出:
bash testing.sh
1
72.00000000000000000000
好的,太好了。
然后如果我将第三行更改为lv=2
bash testing.sh
testing.sh: line 7: 0.094: syntax error: invalid arithmetic operator (error token is ".094")
testing.sh: line 8: 0.094: syntax error: invalid arithmetic operator (error token is ".094")
(standard_in) 2: syntax error
那么我应该如何使用数组中的小数呢?我找不到任何有关 duckduckgoing 的东西。最接近的是 for 循环数组的链接,其中它们计算出如何每步迭代 +0.1。否则它的教程都使用整数。我有一个预先构造的数组,我只需要从中获取值以在表达式中使用。
如果我实际取出 $mycpm 并将其更改为 0.094,则第 10 行将起作用。它会评估得很好。如果能够使用数组来获得这个值,这就是问题所在。
我想在 bash 中实现的目标是可能的吗?
答案1
这里的问题不是数组 - 事实上 bash 不支持非整数的算术评估。对于标量变量甚至标量常量,您会得到相同的错误:
$ bash -c 'echo $((0.094))'
bash: 0.094: syntax error: invalid arithmetic operator (error token is ".094")
其他一些 shell,特别是 zsh、ksh93 和 yash 确实支持它,但请注意,ksh93 和 yash 以自己的方式尊重语言环境的十进制基数字符,并且未引用的算术扩展在 ksh93 和 yash 中都经历了 IFS 分割(如在 bash 中):
$ zsh -c 'echo $((0.094))'
0.094
$ LC_ALL=fr_FR.UTF-8 ksh93 -c 'echo "$((0.094))"'
ksh93: 0.094: radix point '.' requires LC_NUMERIC=C
$ LC_ALL=C ksh93 -c 'echo "$((0.094))"'
0.0939999999999999858
$ LC_ALL=fr_FR.UTF-8 ksh93 -c 'echo "$((0,094))"'
0,0939999999999999858
$ LC_ALL=fr yash -c 'echo "$((0.094))"'
0.094
$ LC_ALL=fr_FR.UTF-8 yash -c 'echo "$((0.094))"'
0,094
然而甚至没有必要尝试要计算 shell 中的表达式 - 您可以将其保留为bc
,只需分配未计算的参数扩展 ${cpm[lv]}
到你的变量:
#!/bin/bash
cpm=(0 1 0.094)
lv=2
attack=5
defense=9
stamina=16
echo "${cpm[lv]}"
mycpm=${cpm[lv]}
#mycpm=$(echo "0.094" | bc -l)
cq=$(echo "$attack*$defense*1/10*sqrt($stamina)*2^2*$mycpm" | bc -l)
echo "$cq"
然后
$ ./testing.sh
0.094
6.76800000000000000000
我还用现代的 $(命令替换)替换了已弃用的“反引号”,并添加了一些引号。