壳

如何在shell中将科学记数法的值转换为十进制数? (首选C壳)

另外我想将它从 e-12 转换为 e-9 然后 shell

42.53e-12 至 0.04253。我必须这样做以获得一个列表。

答案1

printf会从 shell 为你做这件事。

 $ FOO=42.53e-12
 $ BAR=$(printf "%.14f" $FOO)
 $ echo $BAR
 0.00000000004253
 $

在古代+神秘的 C-shell 中,这就是。

$ set FOO=42.53e-12
$ set BAR=`printf "%.14f" $FOO`
$ echo $BAR
0.00000000004253
$

答案2

许多 shell(特别是古老的+神秘的 csh)不理解浮点运算。

在大多数 shell 中都有一个printf可以理解“科学格式”的内置函数。

$ printf '%5.0f\n' '1e3'
 1000

但所有 printf 都可以不是做数学:

$ printf '%5.0f\n' '1e3+1e3'
printf: ‘1e3+1e3’: value not completely converted

对于 csh,有一个分两步解决的方法。 - 首先
将数字转换为小于 18 位的小数(对于 64 位浮点数的 53 位有效位)[a]

    % printf "%.18f\n" "42.53e-12"
    0.000000000042530000
  • 第二次
    乘以1e3(根据您的要求)并再次打印:

    % printf '%.15f\n' "`printf "%.18f" "42.53e-12"`e3"
    0.000000042530000
    

当然,printfincsh是一个具有自己的浮点大小(64 位?)的外部实用程序,并且对于不同的操作系统可能有所不同。

数学工具。

做数学(除了 shell 之外)很自然地会想到bc,但是 bc 有其自身的局限性(不理解e作为指数,它必须转换为10^)。读这个

但 awk 可以做到:

% echo 42.53e-12 | awk '{printf("%.15f\n", $1*1e3)}'
0.000000042530000

不要期望超过 15 个正确数字,因为 awk 使用 53 位有效位。要获得更多,您需要 GNU 版本的 awk,其中编译有任意精度模块。

% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40g\n", $1*1e3)}'
4.253e-08

即 134 个二进制位(最多)40 个十进制数字。作为小数:

% echo 42.53e-12 | awk -M -v PREC=134 '{printf("%.40f\n", $1*1e3)}'
0.0000000425300000000000000000000000000000

列表

在你的问题中,你说:

我必须这样做以获得一个列表。

但没有详细说明它是什么类型的列表。如果列表位于文件内(不是作为 shell 变量),则除了执行以下命令外,您不需要csh(或任何其他 shell)执行任何操作:

% awk '{printf("%.15f\n", $1*1e3)}' <file

与上述相同的精度限制仍然适用。


[A]实际上,从技术上讲,您应该首先限制 printf 格式的位数%g,因此迂腐的正确解决方案是三级转换。

在任何合理的 shell(ksh、bash、zsh)中,这都可以工作:

$ bash -c 'printf "%.15f\n" "$(printf "%.18f" "$( printf "%.18g" "42.53e-12")" )e3"'
0.000000042530000

但是在 csh 中引用 double` `确实很尴尬,并且 csh 用于set分配给变量。简而言之,这适用于csh

$ csh -c 'set a=`printf "%.18g" "42.53e-12"`; set a=`printf "%.18f" "$a"`; printf "%.18f\n" "${a}e3"'
0.000000042530000000

但是,我真的真的!认为你应该避免 csh。

答案3

您可以尝试以下操作:

echo "3.0000000000e+02" | awk '{printf("%d",$0);}'

或者如果您希望有小数

echo ""3.676361000e+02" | awk '{printf("%0.2f",$0);}'

答案4

可能不是最好的解决方案,但我设法通过一点技巧做到了。你可以做这样的事情 -

scientific='42.53e-12'
base=$(echo $scientific | cut -d 'e' -f1)
exp=$(($(echo $scientific | cut -d 'e' -f2)*1))
converted=$(bc -l <<< "$base*(10^$exp)")
>> .00000000004253000000

相关内容