第一章:The Missing Code Library--9.一个任意精度浮点计算器
在脚本的编写过程中,最常用的恐怕就是$(())了。它可以执行多种基本算术运算。这个表达式非常有用,特别是增加计数器时;并且它支持+ - * / %运算,不过不是所有的整数和小数都行。比如,下面的命令返回的是0,而不是0.5:
echo $((1/2))
所以当一个计算结果需要更高的精度时,这也就意味着你接受了一个挑战。在命令行下没有几个好用的计算程序。除了,比如说,bc,一个很少有Unix用户学习的怪异程序。bc程序会把自己当作一个任意精度的计算器,它使用隐晦的错误信息追溯到Unix的开头,并且完全没有提示,而且,一旦你使用它,它就假定你已经非常明了你正在做什么。但这一切都没有关系,我们可以搞定。
代码:
1 #!/bin/sh 2 3 # scriptbc.sh -- 返回计算结果的'bc'封装器 4 5 if [ $1 = "-p" ]; then 6 precision=$2 7 shift 2 8 else 9 precision=2 # 默认为小数点后2位 10 fi 11 12 bc -q << EOF 13 scale=$precision 14 $* 15 quit 16 EOF 17 18 exit 0
脚本如何工作:
这个脚本使用了here document方法,这个方法很有用。标记符号<<允许你在脚本中包含后续输入,这些后续的输入就好像直接从输入流中获得的一样,在本例中,也就是允许用一种简单的机制让bc程序来处理命令。这同样也是我们第一次阐述:在一个脚本内,如何利用命令的参数来增强一个命令的灵活性。这里,如果调用脚本时用了-p选项,它就会允许你给出一个你想要的精度。如果没有给出,程序就默认使用scale=2。
当使用bc时,明白长度(length)和精度(scale)之间的区别尤其重要。对于bc来说,length是数字中的总的个数,而scale则是小数点后的数字个数。因此,10.25的length是4,scale是2,而3.14159的length是6,scale是5。
默认情况下,bc的length是一个变量,但由于它的scale是0,所以如果不加任何设置的话,bc的工作方式和$(())看起来一模一样。幸运的是,如果你在bc中设置了scale的话,你就会发现它有许多隐藏的力量,比如:
bc #命令行上键入bc bc 1.06 #输出的bc版本 Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc. #系统信息 This is free software with ABSOLUTELY NO WARRANTY. #系统信心 For details type `warranty'. #系统信息 scale=10 #设置精度 (2002-1962)*365 #给出计算表达式 14600 #上面算式的结果 14600/7 #再给出一个算式 2085.7142857142 #上面算式的结果 quit # 退出bc程序
为了允许从命令行访问bc,封装脚本必须禁止Copyright内容的输出。就算他们的输入不是来自终端(标准输入),大部分bc版本也知道应该禁止头部Copyright的输出。封装器还将scale设置为一个明确的值,给bc程序传了表达式,然后使用quit命令退出。
运行脚本:
要运行这个脚本,只要给脚本程序一个数学表达式作为参数即可。
运行结果:
1 scriptbc.sh 14600/7 2 2085.71 3 scriptbc.sh -p 10 14600/7 4 2085.7142857142

浙公网安备 33010602011771号