当我使用 bc 在 shell 中执行浮点运算时,如果我使用常规计算器,结果会有所不同。难道我做错了什么?
例如,我需要找到球体的体积。用户输入半径值。
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
。所以4/3
当scale
是 2时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
您应该使用更好的值pi
并允许比例按照默认定义bc
(20 位数字):
$ 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
,
如果您在使用数字小数字符(或)时遇到麻烦.
,您可以使用此版本:
$ 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
但总的来说,这是一个坏主意。