
3つの変数と値があります。
totalLines=14
outsideLines=6
multiplied=600
totalLines
合計行数(100%)を表し、outsideLines
タイムスタンプ値が特定の制限を超える行数を示します。私の目的は、これらの外部線の割合を計算することです。私がこうすれば:
percentage=$(( multiplied / totalLines))
echoの$percentage
結果を得た。
42
しかし、次のように浮動小数点数のパーセンテージを生成したいと思います。
42.85
私はこれを達成しようとしています。
percentage=$( bc <<< 'scale=2; $multiplied / $totalLines' )
次のエラーで失敗します。
(standard_in) 1: illegal character: $
(standard_in) 1: illegal character: $
(standard_in) 1: illegal character: L
(standard_in) 1: syntax error
浮動小数点数のパーセンテージを取得するには、bcをどのように正しく使用する必要がありますか?
答え1
シンプル
実行する必要がある(近似、ゼロに丸め)数学のみの場合は、次のようにほとんどのシェルで直接計算を実行できます。
➤ printf '%8.2f\n' "$((multiplied*100/totalLines))e-2"
42.85
そして、最新バージョンのbash、zsh、またはksh93では、次のように変数に割り当てることができます。
➤ printf -v percentage '%.2f\n' "$((multiplied*100/totalLines))e-2"
➤ echo "$percentage"
42.85
これは整数演算、小数点以下の2桁、空白なしでゼロに丸められたパーセンテージです。
これは、シェルが整数の数学を実行しますが、常に100を掛けた値を計算できるためです。$((…))
その結果、整数は4285になります。
次に、小数点区切り記号(点)を左に2桁移動するだけです。
そのため、e-2
その価値はそのままです4285e-2
。
結果は、小数点以下の2桁の浮動小数点数としてフォーマットされます%8.2f
。
移植性が高いオプションですが、少し遅くなります(サブシェルはフォーク()を意味します)。ほとんどのシェルでは以下を使用します。
percentage="$(printf '%8.2f\n' "$((outsideLines*100*100/totalLines))e-2")"
これはすべてシェル内で行われます(printfが組み込まれている場合)。
外部アプリケーションをロードする必要はありません。これにより速度が速くなり、CPU負荷が軽減されます(例:一つ数字)。
1000文字まで拡張しようとしないでください。シェルはテキストファイルの操作に適したツールではありません。
最近
パーセンテージを最も近い偶数に丸める必要がある場合。 IEEE-754の基本的な丸め方法では、小数部にはより多くの桁を使用する必要があります。次のようにすると、より多くの数字(この場合は13(小数点11桁))が得られます。
$ printf '%.2f\n' "$((outsideLines*10**15/totalLines))e-13"
62.75
$ printf '%.4f\n' "$((outsideLines*10**15/totalLines))e-13"
62.7451
$ printf '%.6f\n' "$((outsideLines*10**15/totalLines))e-13"
62.745098
シェルの整数計算から小数点以下11桁以上を抽出することは意味がありません。倍精度浮動小数点数は(通常)53ビットに制限され、10進数は16ビットを超えません。パーセント数字の整数部分に使用される2桁の数字を減算すると、小数点以下14桁以下が残ります。パーセンテージが小さいほど値が小さくなる(数学は整数値で行われるため)、小数点以下11桁以下しか信頼できません。
紀元前
より高い精度(非常に小さいパーセント)が必要な場合は、シェルの整数数学を使用することは意味がありません。この場合は、bc
直接使用してください(外部プログラムのロードと実行が遅くなります)。
$ bc <<<"scale=30; outsidelines=$outsideLines; totallines=$totalLines; outsidelines*100/totallines"
42.857142857142857142857142857142
$ val="$(bc <<<"scale=30; outsidelines=$outsideLines; totallines=$totalLines; outsidelines*100/totallines")"
$ printf '%.8f' "$val"
42.85714286
$ printf '%.6f' "$val"
42.857143
$ printf '%.4f' "$val"
42.8571
$ printf '%.2f' "$val"
42.86
1 シェル整数算術ラウンド0になる傾向がある。ここでは取り除く42.85714285714285...
ために切りました。42.85
0.00714285714285
²オペレーティングシステムのデフォルトの丸めモードに従って丸めます。通常、最も近い値は偶数と同じです(銀行家の丸め(ただし、一部のオペレーティングシステムでは0に最も近い関係かもしれません。)これは小数点11桁を使用して行われます。たとえば、計算された値が2桁に近い場合、42.86
この値は印刷されます。
答え2
次のことができます。
percentage=$(echo "scale=2; $multiplied / $totalLines" | bc)
答え3
ありがとうスティーブン・チャジェラス 私の変数の誤用を指摘してください
@user2323の仕事を少し終えました。回答:
> printf '%.2f\n' "$((outsideLines*100*100/totalLines))e-2"
> 42.85
最後に「e-2」がつくので、前に100を加えなければなりません。"$((outsideLines*100/totalLines))"
パーセンテージの整数部分のみを取得できます。
> printf '%.2f\n' "$((outsideLines*100/totalLines))"
> 42
、"$((outsideLines*100/totalLines))e-2"
小数点以下の2桁の浮動小数点数を取得しますが、パーセンテージは得られません。
> printf '%.2f\n' "$((outsideLines*100/totalLines))e-2"
> 0.42