bash 在bash中将科学记数法转换为十进制
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13826237/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
convert scientific notation to decimal in bash
提问by kimmyjo221
I would like to convert a number that is stored in scientific notation into a floating point decimal, so I can then perform some comparisons on the data. This is being done in a bash script - here is a small snippet of the code:
我想将以科学记数法存储的数字转换为浮点小数,以便我可以对数据进行一些比较。这是在 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
My problem is that my <operand is selecting basically all of the pressure values, which are stored in scientific notation, when I use <, and none when I use >. I am looking at atmospheric pressure measurements in pascals rather than millibars.
我的问题是我的<操作数基本上选择了所有压力值,这些值以科学记数法存储,当我使用时<,而当我使用时不选择>。我正在查看以帕斯卡而不是毫巴为单位的大气压力测量值。
Here is sample output:
这是示例输出:
Strong Storm From North 0039988 0017 1.0074E+05
Strong Storm From North 0037481 0018 9.9831E+04
Neither of these storms should be meeting the selection criteria!
这些风暴都不应该满足选择标准!
回答by gniourf_gniourf
First thing, bash cannot do arithmetic using floating point arithmetic. Second thing, bash doesn't know scientific notation (even for integers).
首先,bash 不能使用浮点算术进行算术运算。第二件事,bash 不知道科学记数法(即使对于整数)。
First thing you can try, if you're absolutely positively sure that all your numbers are integers: convert them to decimal notation: printfwill happily do that for you:
您可以尝试的第一件事是,如果您绝对肯定所有数字都是整数:将它们转换为十进制表示法:printf将很乐意为您做到这一点:
printf -v pres_inter "%.f" "$pres_inter"
(%.frounds to nearest integer).
(%.f四舍五入到最接近的整数)。
then use bash's arithmetic:
然后使用 bash 的算法:
if (( pres_inter < 97000 )); then ....
This solution is wonderful and doesn't use any external commands or any subshells: speed and efficiency!
这个解决方案很棒,不使用任何外部命令或任何子shell:速度和效率!
Now if you're dealing with non integers you'd better use bcto do the arithmetic: but since bcis 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:
现在,如果您正在处理非整数,您最好用它bc来进行算术运算:但是由于它bc很迟钝并且不能很好地处理科学记数法,因此无论如何您都必须将数字转换为十进制记数法。因此,应该执行以下操作:
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.
当然,这会比较慢,因为你要分叉一个bc. 如果您对整数感到满意,请坚持我给出的第一种可能性。
Done!
完毕!
回答by Gabriele Amorosino
I think the best way to do it is using awk. For example, in the case of the number "1.0074E+05"
我认为最好的方法是使用 awk。例如,在数字“1.0074E+05”的情况下
echo "1.0074E+05" | awk -F"E" 'BEGIN{OFMT="%10.10f"} {print $1 * (10 ^ $2)}'
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 :)
显然你可以使用比十进制更小的精度:)
回答by sampson-chen
For numeric comparisons, you need to use:
对于数字比较,您需要使用:
-eqinstead of==-neinstead of!=-ltinstead of<-leinstead of<=-gtinstead of>-geinstead of>=
-eq代替==-ne代替!=-lt代替<-le代替<=-gt代替>-ge代替>=
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_numfrom scientific notation into a normal decimal integer.
将转换landfall_num从科学记数法到正常的十进制整数。

