2010-05-04 100 views
4

我不得不做的shell脚本一个部门,最好的办法是:如何比较在shell脚本两个浮点值

result1=`echo "scale=3; ($var1/$total) * 100"| bc -l` 
result2=`echo "scale=3; ($var2/$total) * 100"| bc -l` 

,但我想比较的$result1$result2

使用if test $result1 -lt $result2if [ $result1 -gt $result2 ]没有工作:(

任何想法如何做到这一点?

回答

6

您可以莲花比较使用expr(1)克点数:

: [email protected] 3724 ; expr 3.1 '<' 3.3 
1 
: [email protected] 3725 ; expr 3.1 '<' 3.09 
0 

您也可以bc做比较,以及计算:

if [ "$(echo $result1 '<' $result2 | bc -l)" -eq 1 ];then ... fi 

最后,ksh93的可以做算术评估$(($result1 < $result2))与浮点数,虽然bash不能。

+0

'如果[ “$(回声$ resutl1 '>' $ RESULT2 | BC-1)” 当量1];然后'为我工作:) – Reem 2010-05-12 11:19:40

0

请注意,在处理浮点数时要小心一点,如果您正在测试相等性,您确实需要确定一些精度,然后使用它进行比较。例如:

if (abs(x1-x2) < 0.0001) then equal # pseudo-code 

原因是,在计算机中,我们正在处理有限精度的二进制分数而不是真正的数学实数。用scale = 3限制bc的精度会产生这种效果。

我也建议不要试图在shell脚本中做这些事情。这并不是说你不能做到这一点,但是你必须分出许多小的子命令来完成棘手的问题,执行起来很慢,而且通常很难写 - 你花大部分时间试图获取shell做你想做的事,而不是写你真正想要的代码。改为使用更复杂的脚本语言;我的选择语言是perl,但也有其他语言。像这样...

echo $var1 $var2 $total | perl -ne 'my ($var1, $var2, $tot) = split /\s+/; if ($var1/$tot == $var2/$tot) { print "equal\n"; }' 

也注意到,你用相同的值($总在你的问题),所以比较全将可以针对而分子(VAR1和VAR2)提供$总为正进行

0

发布一个新的答案,因为我还不能发表评论...

@Norman Ramsey's answer说法并不准确:

  • expr将PERFO rm是整数或字符串比较,而不是浮点比较。
    这里的手册页说的话:

    表达式1 {=,>,> =,<,< =,=!}表达式2

    返回如果两个自变量的整数比较结果是整数;否则,返回字符串比较的结果,使用特定于语言环境的归类序列。

    (只是尝试expr 8.9 '<' 10并获得0它应该是1)。

  • bc工程很好,但并不总是安装。


所以另一种方法是使用perl -e

  • perl -e 'print expression'将打印1如果表达式为真,没有什么(空字符串),否则。

    例如perl -e 'print 8.9 < 10' - 打印“1”,而perl -e 'print 2>4'什么都不打印。

  • 而在if语句中使用时:

    if [ $(perl -e "print $result1 < $result2") ];then ... fi