我正在试图解决这个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正因为如此,我把解决方案搞错了。知道吗?
发布于 2014-12-07 08:29:33
这里的关键是确保使用带有"%.3f“格式规范的printf,而printf将按照您的意愿进行舍入,只要bc使用"scale=4”即可。
下面是一个实用的脚本:
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。
或者,通过将这里的文档重定向为bc的输入,这也不需要管道,如下所示,它避免了创建子shell:
echo -e "please enter math to calculate: \c"
read x
printf "%.3f\n" $(bc -l <<< "scale=4;$x")发布于 2014-12-07 07:42:55
你不是在舍入这个数字,而是在截断它。
$ 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 }'发布于 2014-12-07 15:21:25
我完全同意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这里面有两件事。
让我们以舍入最近的整数为例,如果将.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.928https://stackoverflow.com/questions/27340666
复制相似问题