一个关于长表达式的bc问题

一个关于长表达式的bc问题

我想在shell中计算一个表达式。我使用以下代码:

pi=$(echo "scale=10; 4*a(1)" | bc -l)
i=3
d=`expr (1+c($pi*($i/10)+$pi))/2 | bc -l`

但它说

bad pattern: (1+c(3.1415926532*(3/10)+3.1415926532))/2

为什么?

答案1

因为您在上一个命令中使用的expr地方可能应该使用echo.

$(…)PS 我建议您在两个命令中使用该形式bc(而不是`…`)。

答案2

请注意,设置比例的位置会对计算产生影响。

这个脚本:

bc -l << \EOF
scale = 10
pi = 4 * a(1)
i = 3
(1 + c(pi * (i / 10) + pi)) / 2
EOF

bc -l << \EOF
pi = 4 * a(1)
i = 3
scale = 10
(1 + c(pi * (i / 10) + pi)) / 2
EOF

bc -l << \EOF
pi = 4 * a(1)
i = 3
r = (1 + c(pi * (i / 10) + pi)) / 2
scale = 10
r/1
EOF

bc -l << \EOF
scale = 100
pi = 4 * a(1)
i = 3
r = (1 + c(pi * (i / 10) + pi)) / 2
scale = 15
r/1
EOF

输出:

.2061073736
.2061073739
.2061073738
.206107373853763

答案3

如果你接受我的建议,你就不会使用 `` 或者$()- 这有点愚蠢。bc是一个交互式的、面向行的解释器。它从标准输入中读取一行,根据刚刚读取的输入检查是否需要另一行,然后将其结果打印到标准输出或在标准输入上提示更多信息。与您的 shell 一样,它甚至会拒绝执行除行缓冲区输出之外的任何操作,即使它被写入终端以外的其他地方。根本不需要bc为每个计算调用一个新的 - 特别是在命令替换中涉及调用一个全新的 shell 并分配一个新的管道。

最好的方法是建立一个协同进程。

# in a bash shell
exec 8<> >( : ) 9< <( bc <&8 )
echo 'b=5;++b' >&8
read  b <&9
echo "$b"

6

并且它将bc继续运行 - 您正在做大量工作以在短暂的、命令替代的进程之间来回穿梭的所有这些变量值bc可以更容易地集中存储在中央bc.

echo b\*b >&8; read b <&9; echo "$b"

32

更好的是,因为我前几天学会了如何执行此操作,您可以将bc进程放在套接字服务器上。

{ ncat -l 9000 --allow localhost -k| bc; } <>/dev/fd/1 |:&

并使用会说该语言的 shell /dev/tcp

{ echo 'b=10;b' >&0; read b; echo "$b"; } <>/dev/tcp/localhost/9000

10

这可能会有点麻烦。我写了一个小函数叫做bchat()让事情变得更容易。

bchat(){
        local IFS=\;                                 ### separate on ;
        printf ${1+'%s;"\n"\n';}"$*"                 ### print \0 if no args
        set --                                       ### init  args
        while  read   bchat       &&                 ### while read <bc
              "${bchat:+set}" -- "$@" "${bchat:=$*}" ### append to args
        do :;  done 2>/dev/null                      ### and done
}       <>"$BC" >&0                                  ### $BC must be set

如上所示设置套接字服务器后,您可以使用该函数,例如:

BC=/dev/tcp/localhost/9000
bchat b=5 x='(b--)' '"x="' ++x '"b="' --b
echo "$bchat" 

x=6;b=3

...再说一遍,只要 bc 进程存在,该状态就会持续存在...

相关内容