语法错误:需要操作数(错误标记为“/”)

语法错误:需要操作数(错误标记为“/”)

我有以下 bash 脚本

# 1 + x^2/2! + x^4/4! + ... + x^(2n)/(2*n)!
#!/bin/bash
factorial() {
    n=$1
    fact=1
    for ((i = 2; i <= $n; i++)); do
        fact=$(expr $fact \* $i)
    done
    return $fact
}

read -p "x = " x
read -p "n = " n

sum=0
for ((i = 1; i <= n; i++)); do
    val=$((2 ** ($i - 1)))
    ex=$(($x ** $val))
    f=$(factorial $val)
    a=$(($ex / $f))
    sum=$(($sum + $a))
done
echo $sum

我正在努力实现上述系列。我不需要解决方案。我只是不明白为什么会出现错误。

错误:

x = 1
n = 2
sum_of_series.sh: line 20: 1 / : syntax error: operand expected (error token is "/ ")

答案1

该错误消息是由 line 引起的,因为(除)运算符a=$(($ex / $f))后面没有操作数。/所以立即怀疑该变量f是一个空字符串。

其原因是分配$( )时命令替换的行为。f当执行封闭的命令管道时,这会收集 stdout 的内容。由于您的factorial()函数未向标准输出写入任何内容,因此分配给 f 的值为空。解决方案是回显或打印该值,代替return-- 例如 as printf '%s\n' "${fact}"

一些可能有用的附加注释:

return 语句中的值代表函数的状态,而不是它可能生成的任何数据。在没有 return 语句的情况下,函数中执行的最后一个命令的退出状态将传递回调用者。

返回状态被截断为 8 位,并且是无符号的,因此只能取范围 0-255。

另外,外部命令的状态还有进一步的约定。由信号终止的进程的状态为 128 + 信号编号。如果 shell 无法创建新进程或执行命令,则可能会返回 126 或 127。状态 0 通常表示成功,从 1 开始的任何小整数表示命令检测到的错误或异常结果。我认为明智的做法是在 shell 函数中遵循相同的约定,并且永远不要以这种方式返回数据值。

Shell 算术(根据 GNU/bash 手册)以固定宽度整数进行计算。在我的系统上,这似乎是 64 位有符号整数,但它可能因系统和发行版而异。 31 位只能容纳 12!,63 位只能容纳 20!,这可能会限制您的范围。

该片段显示 Bash 算术溢出 63 位,大约在 9.22e+18 左右。

Paul--) for k in {1..10}; do
> printf '%s %s\n' $k $(( 3000000000000000000 * k ))
> done
1 3000000000000000000
2 6000000000000000000
3 9000000000000000000
4 -6446744073709551616
5 -3446744073709551616
6 -446744073709551616
7 2553255926290448384
8 5553255926290448384
9 8553255926290448384
10 -6893488147419103232
Paul--) 

对于大数字,我的首选是 dc 命令,它可以不受限制的数字大小,但需要 RPN(反向波兰表示法)。该片段生成 RPN 命令来列出最多 10 的阶乘!

Paul--) { echo 1; seq -s ' p * p ' 2 10; echo ' p * p q'; }
1
2 p * p 3 p * p 4 p * p 5 p * p 6 p * p 7 p * p 8 p * p 9 p * p 10
 p * p q
Paul--) 

这是执行(但我测试了最多 400 个!):

Paul--) { echo 1; seq -s ' p * p ' 2 10; echo ' p * p q'; } | dc
2
2
3
6
4
24
5
120
6
720
7
5040
8
40320
9
362880
10
3628800
Paul--) 

相关内容