我正在努力比较Bash脚本中的两个浮点数。我有两个变量,例如。
let num1=3.17648e-22
let num2=1.5
现在,我想对这两个数字做一个简单的比较:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
不幸的是,我有一些问题与num1的正确处理可以是“电子格式”。
我正在努力比较Bash脚本中的两个浮点数。我有两个变量,例如。
let num1=3.17648e-22
let num2=1.5
现在,我想对这两个数字做一个简单的比较:
st=`echo "$num1 < $num2" | bc`
if [ $st -eq 1]; then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
不幸的是,我有一些问题与num1的正确处理可以是“电子格式”。
当前回答
对于非整数数学,最好使用AWK。你可以使用这个Bash实用函数:
numCompare() {
awk -v n1="$1" -v n2="$2" 'BEGIN {printf "%s " (n1<n2?"<":">=") " %s\n", n1, n2}'
}
称之为:
numCompare 5.65 3.14e-22
5.65 >= 3.14e-22
numCompare 5.65e-23 3.14e-22
5.65e-23 < 3.14e-22
numCompare 3.145678 3.145679
3.145678 < 3.145679
其他回答
一个非常简单的perl解决方案:
$ num1=3.2E8
$ num2=2.5E9
$ perl -e "print $num2 > $num1? \"true\" : \"false\", \"\n\";"
true
$ perl -e "print $num2 < $num1? \"true\" : \"false\", \"\n\";"
false
这证明perl真正理解科学数字表示的“E”符号:
$ perl -e "print $num1, \"\n\";"
320000000
如果你在shell脚本中需要一个' If '语句,在perl中使用exit命令:
$ if perl -e "exit ($num1 > $num2? 0 : 1);"; then echo true; else echo false; fi
false
注意,在shell脚本中,返回0的命令表示成功,并传递'if'条件(因此if-子句被执行)。任何其他非零返回值都意味着失败。
更加方便
这可以使用Bash的数值上下文更方便地完成:
if (( $(echo "$num1 > $num2" |bc -l) )); then
…
fi
解释
通过基本计算器命令bc的管道将返回1或0。
选项-l等价于——mathlib;它加载标准数学库。
将整个表达式括在双括号(())之间会将这些值分别转换为true或false。
请确保安装了bc基本计算器包。
注意:指数符号应该写成*10^;不是E,也不是E。
例如:
$ echo "1*10^3==1000" |bc
1
而
$ echo "1E3==1000" |bc
0
这里讨论了克服这种bc限制的策略。
使用KornShell。在Bash中,你可能需要单独比较小数部分:
#!/bin/ksh
X=0.2
Y=0.2
echo $X
echo $Y
if [[ $X -lt $Y ]]
then
echo "X is less than Y"
elif [[ $X -gt $Y ]]
then
echo "X is greater than Y"
elif [[ $X -eq $Y ]]
then
echo "X is equal to Y"
fi
有一种简单的方法,比AWK快一点,而且不需要安装bc。它利用sort对浮点数进行排序的能力:
A=1280.4
B=9.325
LOW=$(sort -n <<< "$A"$'\n'"$B" | head -1)
if [[ "$LOW" == "$A" ]]; then
echo "A <= B"
else
echo "A >= B"
fi
当然,对于相等的数字,这是行不通的。
你可以使用AWK结合Bash if条件:
if awk "BEGIN {exit !($d1 >= $d2)}"; then
echo "yes"
else
echo "no"
fi