第一章: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

 

posted @ 2012-12-10 17:19  十舍七匹狼  阅读(660)  评论(0)    收藏  举报