長い表現に関するBC質問

長い表現に関するBC質問

シェルで式を評価したいです。次のコードを使用します。

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インタラクティブなライン指向インタプリタです。標準入力から 1 行を読み、今読み取った入力に基づいて別の行が必要かどうかを確認し、その結果を標準出力として印刷するか、標準入力に関する追加情報を求めるメッセージを表示します。シェルと同様に、端末以外の場所に書き込まれても、ラインバッファ出力以外の操作を拒否します。bc各計算で新しいものを呼び出す必要はありません。特にコマンド置換ではさらにそうです。返品まったく新しいシェルを呼び出し、新しいパイプを割り当てる作業が含まれます。

最善の方法は、コラボレーションプロセスを設定することです。

# 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 |:&

次の言語を使用するシェルを使用してください/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プロセスが存在する限り持続します...

関連情報