【问题标题】:How to compare two floating-point values in shell script如何在shell脚本中比较两个浮点值
【发布时间】:2011-02-15 17:08:50
【问题描述】:

我必须在 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 ] 不起作用:(

知道怎么做吗?

【问题讨论】:

    标签: linux comparison shell conditional-statements bc


    【解决方案1】:

    您可以使用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 &lt; $result2)) 进行算术评估,尽管 bash 不能。

    【讨论】:

    • ` if [ "$(echo $resutl1 '>' $result2 | bc -l)" -eq 1 ];then ` 对我有用 :)
    【解决方案2】:

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

    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"; }'
    

    还请注意,您要除以相同的值(您的问题中的 $total),因此如果 $total 为正数,则可以针对分子(var1 和 var2)进行整个比较

    【讨论】:

      【解决方案3】:

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

      @Norman Ramsey's answer 不太准确:

      • expr 将执行整数或字符串比较,而不是浮点比较。
        手册页是这样写的:

        expr1 {=, >, >=,

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

        (只需尝试expr 8.9 '&lt;' 10 并得到0 应该是1)。

      • bc 效果很好,但并不总是安装。


      所以另一种选择是使用perl -e

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

        例如perl -e 'print 8.9 &lt; 10' - 打印“1”,而perl -e 'print 2&gt;4' 不打印任何内容。

      • 当用于if 声明时:

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

      【讨论】:

        猜你喜欢
        • 2021-03-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-29
        • 2010-12-08
        • 1970-01-01
        相关资源
        最近更新 更多