如何在Shell脚本中比较两个浮点数值

4

我需要在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 ]没有起作用:(

有什么办法吗?

3个回答

6
您可以使用expr(1)比较浮点数:
: nr@yorkie 3724 ; expr 3.1 '<' 3.3
1
: nr@yorkie 3725 ; expr 3.1 '<' 3.09
0

您也可以让bc执行比较和计算:
if [ "$(echo $result1 '<' $result2 | bc -l)" -eq 1 ];then ... fi

最后,ksh93可以对浮点数进行算术运算评估:$(($result1 < $result2)),而bash不能。

如果 [ "$(echo $resutl1 '>' $result2 | bc -l)" -eq 1 ];then 这段代码对我有效 :) - Reem

0

请注意,在处理浮点数时必须小心,如果您要测试相等性,确实需要决定一些精度,然后使用该精度进行比较。类似这样:

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

原因是我们在处理计算机时,使用的是有限精度的二进制小数而不是真正的数学实数。在bc中通过设置scale=3来限制精度将产生这种效果。

我也建议不要尝试在shell脚本中完成这些工作。并不是说你不能做到,但你必须分叉出许多小的子命令来完成棘手的部分,这会导致执行速度变慢,通常很难编写 - 你会花费大部分时间来尝试让shell做你想要的事情,而不是编写你真正想要的代码。相反,转向更复杂的脚本语言;我的选择是perl,但还有其他语言可以选择。像这样...

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

还要注意,您正在使用相同的值进行除法运算(在您的问题中为 $total),因此只要 $total 为正数,就可以对提供的分子(var1 和 var2)进行整个比较


0

由于我还不能评论,所以发表一个新的答案...

@Norman Ramsey's answer 不太准确:

  • expr 将执行整数或字符串比较,而不是浮点比较。
    这是 man 页面上的说明:

    expr1 {=, >, >=, <, <=, !=} expr2

    如果两个参数都是整数,则返回整数比较的结果;否则,使用特定于语言环境的排序顺序返回字符串比较的结果。

    (只需尝试 expr 8.9 '<' 10 并获得应该是 10 即可明白)。

  • 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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接