web-dev-qa-db-ja.com

シェルで値を科学表記から10進数に変換しますか?

シェルで値を科学表記から10進数に変換する方法は? (推奨Cシェル)

また、e-12からe-9に変換してからシェルに変換したいと思います

42.53e-12から0.04253。リストのためにこれをしなければなりません。

5
cHiRaG

printfはシェルからこれを行います。

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

古代+難解なCシェルでは、これはそうなります。

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

シェル

多くのシェル(特に古代+難解なcsh)は、浮動小数点演算を理解していません。

ほとんどのシェルには、「科学的フォーマット」を理解する組み込みのprintfがあります。

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

しかし、すべてのprintfは計算できません計算できません

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

Cshには2つのステップで回避策があります。 - 最初
数値を18桁未満の10進数に変換します(64ビット浮動小数点のうち53ビット有効の場合)。[a]

    % printf "%.18f\n" "42.53e-12"
    0.000000000042530000
  • 二番目
    (要求どおりに)1e3を掛けて、もう一度印刷します。

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

もちろん、printfcshは、独自のフロートサイズ(64ビット?)を持つ外部ユーティリティであり、OSによって異なる場合があります。

数学ツール。

数学(シェル以外)を行うにはbcを考えるのが自然ですが、bcには独自の制限があります(eを指数として理解していないため、10^に変換する必要があります)。 これを読む

しかし、awkはそれを行うことができます。

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

Awkは53ビットの有効桁数を使用するため、15桁を超える正しい数字を期待しないでください。より多くを得るには、GNU awkのバージョンで、任意精度モジュールがコンパイルされている必要があります。

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

これは、40桁までの10進数で134バイナリビットです。 10進数として:

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

リスト

あなたの質問では、あなたは述べています:

リストのためにこれをしなければなりません。

しかし、それがどのようなリストであるかについての詳細は明記しないでください。リストが(シェル変数としてではなく)ファイル内にある場合、csh(または他のシェル)からは、これを実行する以外は何も必要ありません。

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

上記と同じ精度の制限が適用されます。


[a] 実際には、技術的に正確にするために、最初に%g printf形式で桁数を制限する必要があります。そのため、明確な解決策は3レベルの変換です。

妥当なシェル(ksh、bash、zsh)では、これは機能します。

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

しかし、二重の` `を引用するとcshでは実際に扱いにくくなり、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は避けてください。

1
Isaac

最善の解決策とは言えないかもしれませんが、少しハックするだけでなんとかできました。あなたはこのようなことをすることができます-

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
0
markroxor

以下を試すことができます:

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

または小数があると予想される場合

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