bc を使用してシェルで浮動小数点演算を実行する場合、通常の計算機を使用すると結果が異なります。私は何が間違っていましたか?
たとえば、球の体積を求める必要があります。ユーザーは半径の値を入力します。
pi = 3.14
volume=$(echo "scale = 2; (4 / 3) * $pi * ($r ^ 3)" | bc)
echo "Volume is $volume"
半径 = 3 の場合、unix は 112.59 を返し、計算機は 113.1 を返します。
答え1
あなたが理解すべきこと表現の規模存在するbc
。bc
できる任意の精度(これが必ずしも無限の精度を意味するわけではありません。)計算者プロセッサの精度やfloat
データ型がある可能性があります。double
存在するbc
。これスケール点の後の小数点以下の桁数なので精度に関係があります。これスケール式の値は、scale
関連する演算子と変数に依存する規則によって決まります(変数は式を提供する変数です)。普段着寸法正確つまりbc
、好きなだけ正確に作成できます。
たとえば、除算結果の小数点以下の桁数はですscale
。だからが2の4/3
とき、そうです。非常におおよその近似です。の規模は(の規模との規模はどこにありますか?)ので、ここではです。そうなるでしょう。scale
1.33
4/3
x * y
min(a+b,max(scale,a,b))
a
x
b
y
2
1.33 * 3.14
4.17
ルールを確認するにはPOSIX仕様bc
。
より高い精度が必要な場合は増やしてくださいscale
。無限に増やすことができます。を使用するとbc -l
自動的scale
に設定されます20
。
$ pi='(a(1)*4)' r=3
$ $ echo "(4 / 3) * $pi * ($r ^ 3)" | bc -l
113.09733552923255658339
$ echo "scale=1000; (4 / 3) * $pi * ($r ^ 3)" | bc -l
113.0973355292325565846551617980621038310980983775038095550980053230\
81390626303523950609253712316214447357331114478163039295378405943820\
96034211293869262532022821022769726978675980014720642616237749375071\
94371951239736040606251233364163241939497632687292433484092445725499\
76355759335682169861368969085854085132237827361174295734753154661853\
14730175311724413325296040789909975753679476982929026989441793959006\
17331673453103113187002257495740245517842677306806456786589844246678\
87098096084205774588430168674012241047863639151096770218070228090538\
86527847499397329973941181834655436308584829346483609858475202045257\
72294881898002877683392804259302509384339728638724440983234852757850\
73357828522068813321247512718420036644790591105239053753290671891767\
15857867345960859999994142720979823815034238137946746942088054039248\
86988951308030971204086612694295227741563601129621951039171511955017\
31142218396089302929537125655435196874321744263099764736353375070480\
1468800991581641650380680694035580030527317911271523
$ echo "scale=1; (4 / 3) * $pi * ($r ^ 3)" | bc -l
97.2
また、すべての計算にhighを使用し、scale
最終的に表示のためにこれを減らすこともできます。
$ echo "scale=10; (4 / 3) * $pi * ($r ^ 3)" | bc -l
113.0973355107
$ echo "scale=100; x = (4 / 3) * $pi * ($r ^ 3); scale = 10; x / 1" | bc -l
113.0973355292
答え2
より良い値を使用し、スケールをデフォルト値(20桁)pi
として定義できるようにする必要があります。bc
$ echo "r=3; pi=4*a(1); (4/3)*pi*(r^3)" | bc -l
113.09733552923255658339
これは計算を実行するより良い方法です。倍率は、結果の数値出力形式を指定するパラメータではなく、計算に使用される精度を定義するパラメータです。
数値書式を指定するには、printf を使用できます。
$ result="$(echo "r=3; pi=4*a(1); (4/3)*pi*(r^3)" | bc -l)"
$ printf '%.2f' "$result"
113.10
,
数字の 10 進文字 ( または ) の使用に問題がある場合は、次の.
バージョンを使用できます。
$ LC_NUMERIC=C printf '%.2f' "$result"
113.10
printf は IEEE 754 に従って数値丸めを実装します。
もちろん、最後に小数点以下の桁数を変更して、bcが小数点以下の桁数を切り捨てることができます。
$ echo "r=3; pi=4*a(1); res=(4/3)*pi*(r^3); scale=2; res/1" | bc -l
113.09
しかし、全体的にこれは悪い考えです。