我正在基于此比较 shell 脚本中的浮点值参考。以下是脚本内容
num1=50.960
num2=6.65E+07
echo "${num1} < ${num2}" | bc
当我运行脚本时,输出为“0”。但根据比较应该是“1”。我需要了解为什么比较没有按预期进行?
答案1
该bc
实用程序无法理解6.65E+07
您想要的数字。
在 OpenBSD 上,E
这里是十六进制,所以6.65E
是 6.664 (6.65 + 0.014),然后+07
加 7,得到 13.664,这显然小于 50.960。在 GNU 系统上,6.65E
这6.659
也不是您想要的。
相反,您希望num2
成为字符串6.65*10^7
或66500000
。
$ num1=50.960; num2='6.65*10^7'; printf '%s < %s\n' "$num1" "$num2" | bc
1
答案2
如果你想按原样使用 num2 你可以使用 awk:
awk -v num1="$num1" -v num2="$num2" 'BEGIN{exit num1<=num2}'
这将比较两个数字,如果 num1 小于 num2,则退出 1,否则退出 0。
注意:如果 num1 和 num2 相等,这将退出 1,这与您在这种情况下从 bc 看到的行为相同,如果您希望它在这种情况下退出 0,您将需要使用<
而不是<=
.
答案3
dc
一种方法是首先将工程符号转换为浮点来使用该实用程序。
num1=50.960
num2=6.65E+07
set -- "$num1" "$num2"
e2f() {
case $1 in
*[eE]*) :;;
*) set -- "$1e0"
esac
set -- "${1//+/}"
set -- "${1//-/ _}"
set -- "${1//[eE]/ 10 }"
echo "$1^*"
}
eCmp() {
test "$(dc -e "
15k[1p]sa$(e2f "$1") $(e2f "$2")r>a")" = 1
}
## and then...
if eCmp "$@"
then
echo "$1 > $2"
else
echo "$1 <= $2"
fi
输出:
50.960 <= 6.65E+07
答案4
是的,bc
可以执行各种数学运算。但它不理解浮动。现代 shell 的 printf 可以理解浮点数,但不能进行数学运算。
让我们加入他们吧:
$ num1=50.960
$ num2=6.65E+07
$ printf '%f < %f\n' "$num1" "$num2" | bc -l
1