在bash中将科学记数法转换为十进制

Posted

技术标签:

【中文标题】在bash中将科学记数法转换为十进制【英文标题】:convert scientific notation to decimal in bash 【发布时间】:2012-11-29 08:36:57 【问题描述】:

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

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

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

这是示例输出:

Strong Storm From North 0039988 0017 1.0074E+05

Strong Storm From North 0037481 0018 9.9831E+04

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

【问题讨论】:

为什么不只使用 perl 单行? 【参考方案1】:

首先,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。如果您对整数感到满意,请坚持我给出的第一种可能性。

完成!

【讨论】:

【参考方案2】:

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

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

输出:

100740.0000000000

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

【讨论】:

这应该是公认的答案。短而甜。也适用于底片。现在我可以在我的终端中获得 SHIB 的价格了 :)【参考方案3】:

对于数值比较,你需要使用:

-eq 而不是 == -ne 而不是 != -lt 而不是 &lt; -le 而不是 &lt;= -gt 而不是 &gt; -ge 而不是 &gt;=

并修复一些语法问题:

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 从科学计数法转换为普通十进制整数。

【讨论】:

谢谢。只是好奇——我上周刚参加了一个 shell 编程课程,他们并没有谈论所有的引号。为什么你认为这种语法更好?谢谢! 另外,我收到以下错误:第 28 行:[[:1.0062E+05:语法错误:算术运算符无效(错误标记为“.0062E+05”) 最好将变量用双引号括起来,以消除空字符串或包含换行符的字符串等极端情况。 不要将[[ 用于算术比较,除非与其他一些使用单个命令更简洁的测试相结合。通常,使用(()) 进行算术运算。 Bash 不会处理浮点数,因此这两种方法都不起作用。 @kimmyjo221 这是因为 sci-notation 尚未转换。 bash 本身不支持浮点比较,如果整数没问题,请参阅更新的答案。

以上是关于在bash中将科学记数法转换为十进制的主要内容,如果未能解决你的问题,请参考以下文章

在python中将数组的元素从科学计数法转换为十进制计数法

在 C++ 中将科学计数法转换为十进制

在没有科学计数法的 SQL Server 中将 float 转换为 varchar

如何在 Python 中将负指数数转换为十进制数?

在 hive 中将 bigint 转换为科学数

使用ggplot从科学记数法转换为十进制