我正在努力比较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的正确处理可以是“电子格式”。
当前回答
我使用这里的答案,并把它们放在一个函数中。你可以这样使用它:
is_first_floating_number_bigger 1.5 1.2
result="${__FUNCTION_RETURN}"
一旦被调用,echo $result在这种情况下将为1,否则为0。
功能:
is_first_floating_number_bigger () {
number1="$1"
number2="$2"
[ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
result=$?
if [ "$result" -eq 0 ]; then result=1; else result=0; fi
__FUNCTION_RETURN="${result}"
}
或者带有调试输出的版本:
is_first_floating_number_bigger () {
number1="$1"
number2="$2"
echo "... is_first_floating_number_bigger: comparing ${number1} with ${number2} (to check if the first one is bigger)"
[ ${number1%.*} -eq ${number2%.*} ] && [ ${number1#*.} \> ${number2#*.} ] || [ ${number1%.*} -gt ${number2%.*} ];
result=$?
if [ "$result" -eq 0 ]; then result=1; else result=0; fi
echo "... is_first_floating_number_bigger: result is: ${result}"
if [ "$result" -eq 0 ]; then
echo "... is_first_floating_number_bigger: ${number1} is not bigger than ${number2}"
else
echo "... is_first_floating_number_bigger: ${number1} is bigger than ${number2}"
fi
__FUNCTION_RETURN="${result}"
}
只需要将函数保存在一个单独的.sh文件中,并像这样包含它:
. /path/to/the/new-file.sh
其他回答
AWK和类似的工具(我在盯着你看sed…)应该被扔进旧项目的垃圾箱里,因为它们的代码是用永不读的语言写的,所以每个人都不敢碰。
或者你是一个相对罕见的需要优先考虑CPU使用优化而不是代码维护优化的项目……既然如此,那就继续吧。
如果不是,那么就使用一些可读且显式的语言,比如Python。你的程序员同事和未来的自己都会感谢你。您可以像所有其他代码一样,在Bash中使用Python代码。
num1=3.17648E-22
num2=1.5
if python -c "exit(0 if $num1 < $num2 else 1)"; then
echo "yes, $num1 < $num2"
else
echo "no, $num1 >= $num2"
fi
当比较包版本的数字时要注意,比如检查grep 2.20是否大于版本2.6:
$ awk 'BEGIN { print (2.20 >= 2.6) ? "YES" : "NO" }'
NO
$ awk 'BEGIN { print (2.2 >= 2.6) ? "YES" : "NO" }'
NO
$ awk 'BEGIN { print (2.60 == 2.6) ? "YES" : "NO" }'
YES
我用这样一个shell/AWK函数解决了这样的问题:
# Get version of GNU tool
toolversion() {
local prog="$1" operator="$2" value="$3" version
version=$($prog --version | awk '{print $NF; exit}')
awk -vv1="$version" -vv2="$value" 'BEGIN {
split(v1, a, /\./); split(v2, b, /\./);
if (a[1] == b[1]) {
exit (a[2] '$operator' b[2]) ? 0 : 1
}
else {
exit (a[1] '$operator' b[1]) ? 0 : 1
}
}'
}
if toolversion grep '>=' 2.6; then
# Do something awesome
fi
一行程序解决方案
假设有两个变量A和B,
echo "($A > $B) * $B + ($A < $B) * $A" | bc
为了简单和清晰,只需使用AWK进行计算,因为它是一个标准的Unix工具,所以很可能与bc一样,而且在语法上更容易使用。
对于这个问题:
$ cat tst.sh
#!/bin/bash
num1=3.17648e-22
num2=1.5
awk -v num1="$num1" -v num2="$num2" '
BEGIN {
print "num1", (num1 < num2 ? "<" : ">="), "num2"
}
'
$ ./tst.sh
num1 < num2
另一个问题和这个问题是一样的
$ cat tst.sh
#!/bin/bash
read -p "Operator: " operator
read -p "First number: " ch1
read -p "Second number: " ch2
awk -v ch1="$ch1" -v ch2="$ch2" -v op="$operator" '
BEGIN {
if ( ( op == "/" ) && ( ch2 == 0 ) ) {
print "Nope..."
}
else {
print ch1 '"$operator"' ch2
}
}
'
$ ./tst.sh
Operator: /
First number: 4.5
Second number: 2
2.25
$ ./tst.sh
Operator: /
First number: 4.5
Second number: 0
Nope...
我把这个作为“4.5:语法错误:无效的算术运算符(错误标记是“.5”)”的答案发布-但代码似乎仍然可以工作。为什么?当它作为这个问题的副本关闭时,这里它也适用于这里。
请检查以下编辑代码:
#!/bin/bash
export num1=(3.17648*e-22)
export num2=1.5
st=$((`echo "$num1 < $num2"| bc`))
if [ $st -eq 1 ]
then
echo -e "$num1 < $num2"
else
echo -e "$num1 >= $num2"
fi
这很有效。