7

我想将一个以科学计数法存储的数字转换为浮点十进制数,这样我就可以对数据进行一些比较。这是在 bash 脚本中完成的 - 这是一小段代码:

while read track_id landfall_num gate_id pres_inter
do
  if [[ $landfall_num == 0001 ]]
  then
     start_flag = true
     echo DING DING $start_flag
     if [[ $pres_inter < 97000 ]]
     then
        echo Strong Storm From North $track_id, $gate_id, $pres_inter
     fi
  fi
done < $file

我的问题是我的<操作数基本上选择了所有压力值,当我使用时,它们以科学计数法存储,而当我使用时则<没有>。我正在查看以帕斯卡而不是毫巴为单位的大气压力测量值。

这是示例输出:

Strong Storm From North 0039988 0017 1.0074E+05

Strong Storm From North 0037481 0018 9.9831E+04

这些风暴都不应该满足选择标准!

4

3 回答 3

7

首先,bash 不能使用浮点算术进行算术运算。第二件事,bash 不知道科学记数法(即使是整数)。

如果您绝对肯定所有数字都是整数,您可以尝试的第一件事:将它们转换为十进制表示法:printf很乐意为您做到这一点:

printf -v pres_inter "%.f" "$pres_inter"

%.f四舍五入到最接近的整数)。

然后使用bash的算术:

if (( pres_inter < 97000 )); then ....

这个解决方案很棒,不使用任何外部命令或任何子shell:速度和效率!

现在,如果您正在处理非整数,则最好使用bc算术运算:但是由于bc迟钝并且不能很好地处理科学记数法,因此无论如何您都必须将数字转换为十进制记数法。因此,应该执行以下操作:

printf -v pres_inter "%f" "$pres_inter"
if (( $(bc -l <<< "$pres_inter<97000") )); then ...

当然,这会更慢,因为你正在分叉一个bc. 如果您对整数感到满意,请坚持我给出的第一种可能性。

完毕!

于 2012-12-11T18:53:40.963 回答
5

我认为最好的方法是使用 awk。例如,在数字“1.0074E+05”的情况下

echo "1.0074E+05" | awk -F"E" 'BEGIN{OFMT="%10.10f"} {print $1 * (10 ^ $2)}'

输出:

100740.0000000000

显然你可以使用小于十进制的精度:)

于 2019-05-22T12:48:56.720 回答
2

对于数字比较,您需要使用:

  • -eq代替==
  • -ne代替!=
  • -lt代替<
  • -le代替<=
  • -gt代替>
  • -ge代替>=

并修复一些语法问题:

while read track_id landfall_num gate_id pres_inter
do
  landfall_num=$(printf "%f", "$landfall_num")
  if [[ "$landfall_num" -eq 1 ]]
  then
     start_flag="true"
     echo "DING DING $start_flag"
     if [[ "$pres_inter" -lt 97000 ]]
     then
        echo "Strong Storm From North $track_id, $gate_id, $pres_inter"
     fi
  fi
done < "$file"

更新:

这是将科学记数法数字转换为整数的方法:

printf "%.0f\n", 1.0062E+05

例如,打印:

100620

所以:

landfall_num=$(printf "%f", "$landfall_num")

将从landfall_num科学记数法转换为正常的十进制整数。

于 2012-12-11T18:44:03.907 回答