convert scientific notation to decimal in bash

ぃ、小莉子 提交于 2019-11-30 20:37:04

First thing, bash cannot do arithmetic using floating point arithmetic. Second thing, bash doesn't know scientific notation (even for integers).

First thing you can try, if you're absolutely positively sure that all your numbers are integers: convert them to decimal notation: printf will happily do that for you:

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

(%.f rounds to nearest integer).

then use bash's arithmetic:

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

This solution is wonderful and doesn't use any external commands or any subshells: speed and efficiency!

Now if you're dealing with non integers you'd better use bc to do the arithmetic: but since bc is retarded and doesn't deal well with the scientific notation, you have to convert your numbers to decimal notation anyways. So something like the following should do:

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

Of course, this is slower since you're forking a bc. If you're happy with integers, just stick to the first possibility I gave.

Done!

For numeric comparisons, you need to use:

  • -eq instead of ==
  • -ne instead of !=
  • -lt instead of <
  • -le instead of <=
  • -gt instead of >
  • -ge instead of >=

And to fix some syntax issues:

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"

Updated:

This is how you convert a scientific notation number into an integer:

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

for example, prints:

100620

And so:

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

will convert landfall_num from scientific notation into a normal decimal integer.

I think the best way to do it is using awk. For example, in the case of the number "1.0074E+05"

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

the output:

100740.0000000000

obviously you can use less precision then 10 decimal :)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!