bc算术错误

时间:2014-12-07 07:32:18

标签: math arithmetic-expressions bc

我正在尝试解决这个bash脚本,该脚本从用户读取算术表达式并将其回显到输出屏幕,最后向上舍入3个小数位。

示例输入

5+50*3/20 + (19*2)/7

示例输出

17.929

我的代码是

read x
echo "scale = 3; $x" | bc -l

当输入

5+50*3/20 + (19*2)/7

**我的输出是**

17.928

机器希望它

17.929

由于这个原因,我得到的解决方案是错误的。任何想法?

3 个答案:

答案 0 :(得分:4)

这里的关键是确保使用格式规格为“%。3f”的printf,printf将根据您的意愿进行舍入,只要“scale = 4”为bc。

这是一个有效的脚本:

echo -e "please enter math to calculate: \c"
read x
printf "%.3f\n" $(echo "scale=4;$x" | bc -l)

如果您在命令行运行此命令,您可以了解上述解决方案的内容:echo "scale=4;5+50*3/20 + (19*2)/7" | bc结果将是17.9285。当该结果作为参数提供给printf时,该函数会考虑第四个小数位并将值向上舍入,以便格式化结果显示精确的三位小数,值为17.929。

或者,这也可以通过将here文档重定向为bc的输入而没有管道,如下所示,这样可以避免创建子shell:

echo -e "please enter math to calculate: \c"
read x
printf "%.3f\n" $(bc -l <<< "scale=4;$x")

答案 1 :(得分:3)

你没有四舍五入,你正在截断它。

$ echo "5+50*3/20 + (19*2)/7" | bc -l
17.92857142857142857142
$ echo "scale = 3; 5+50*3/20 + (19*2)/7" | bc -l
17.928

我知道对数字进行舍入的唯一方法是使用awk

$ awk  'BEGIN { rounded = sprintf("%.3f", 5+50*3/20 + (19*2)/7); print rounded }'
17.929

所以,在你的例子中:

read x
awk  'BEGIN { rounded = sprintf("%.3f", $x; print rounded }'

答案 2 :(得分:1)

我完全同意jherran你没有对数字进行舍入,你是在截断它。我会继续说,规模可能只是没有按照你想要的方式表现,可能是没有人希望它表现的方式。

> x="5+50*3/20 + (19*2)/7"
> echo "$x" | bc -l
17.92857142857142857142
> echo "scale = 3; $x" | bc -l
17.928

此外,because of the behaviour of scale,您将每个乘法/除法与加法分开。让我用一些例子证明我的观点:

> echo "scale=0; 5/2" | bc -l
2
> echo "scale=0; 5/2 + 7/2" | bc -l
5
> echo "5/2 + 7/2" | bc -l
6.00000000000000000000

然而,没有任何操作的比例也不起作用。有一个丑陋的解决方法:

> echo "scale=0; 5.5" | bc -l
5.5
> echo "scale=0; 5.5/1" | bc -l
5

因此,事情就会出现。

  • 如果您想使用bc的缩放比例,请仅针对已计算的最终结果执行此操作,即便如此,请注意。

  • 请记住,舍入与截断所需精度的数字+一半相同。

让我们以舍入到最接近的整数为例,如果将.5添加到应该向上舍入的数字,其整数部分将采用下一个整数值,截断将给出所需的结果。如果该数字应该向下舍入,那么添加.5将不会更改其整数值,并且截断将产生与​​添加任何内容时相同的结果。

因此我的解决方案如下:

> y=$(echo "$x" | bc -l)
> echo "scale=3; ($y+0.0005)/1" | bc -l # scale doesn't apply to the +, so we get the expected result
17.929

再次注意,以下内容不起作用(如上所述),因此真正需要在两个操作中将其分解:

> echo "scale=3; ($x+0.0005)/1" | bc -l
17.928