shell 中的浮点比较

shell 中的浮点比较

我正在基于此比较 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.65E6.659也不是您想要的。

相反,您希望num2成为字符串6.65*10^766500000

$ 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

相关内容