bc 的浮点运算不精确?

Sla*_*ado 4 shell bc floating-point

当我使用 bc 在 shell 中执行浮点运算时,如果我使用常规计算器,结果就不一样了。难道我做错了什么?

例如,我需要找到一个球体的体积。用户输入半径值。

pi = 3.14

volume=$(echo "scale = 2; (4 / 3) * $pi * ($r ^ 3)" | bc)
echo "Volume is $volume"
Run Code Online (Sandbox Code Playgroud)

如果radius = 3,unix 返回112.59,计算器返回113.1。

Sté*_*las 14

你需要了解的意思表达的规模bcbc可以做任意精度(不一定意味着无限精度),而您的计算器可能具有处理器的floatdouble数据类型的精度。

bc. 该规模是小数点之后的数字,所以相关的精度。该规模的表达而决定基于依赖于哪个运营商参与和规则的scale变量(该变量是一个给任意的尺寸精度bc是,只要你想,可以使其精度为大)。

例如,除法结果的尺度是scale。所以4/3when scaleis 2 is 1.33,所以非常粗略的近似4/3x * ywill的尺度是min(a+b,max(scale,a,b))(其中a是 的尺度xb的尺度y),所以这里2。所以1.33 * 3.144.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
Run Code Online (Sandbox Code Playgroud)

您还可以使用 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
Run Code Online (Sandbox Code Playgroud)