bash算術の除算でほとんどのパーセンテージが0として計算されるのはなぜですか?


15

スクリプトのbash算術を試みますが$e、最後まで更新されません。出力はそれ自体を物語っています。

max=5
for e in $(seq 1 1 $max); do 
    percent=$(( $e/$max*100 ))
    echo "echo $e / $max : = $percent"
done

Tl; DR:1..5をパーセントで表示します。

出力:

echo 1 / 5 : = 0
echo 2 / 5 : = 0
echo 3 / 5 : = 0
echo 4 / 5 : = 0
echo 5 / 5 : = 100

どうしてこれなの?


1
関連:バッシュのみ計算を行うときにかかわらず、入力の出力として整数を与える(ただしを、問題はここに記載とは異なり、その操作を再順序付けすることによって十分に解決することはできません。)
Eliahケーガン

回答:


24

bash非整数演算を処理できません。すべての式が整数である限り、正しい結果が得られます。したがって、計算のどこかで非整数値を取得しないようにする必要があります。

あなたの場合、などを評価しているとき1 / 52 / 5いくつかの非整数値に対応するbashに整数のゼロ値を作成し、それに応じて結果がゼロになります。除算と乗算の優先順位は同じであり、同じ先行演算子は、式に配置されるときに常に左から右に実行されます。

回避策の1つは、最初に乗算を実行し、次に除算を実行して、bashが非整数値を処理する必要がないようにすることです。修正された式は、

$ max=5; for e in $(seq 1 1 $max); do percent=$(( $e*100/$max )); echo "echo $e / $max : = $percent"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

1
部分式1/5非整数値を作成しません。5による整数除算0結果は0 であるため、整数値を作成します。以降の操作では、その値を正常に使用します。これはOPが意図したものではありませんが、整数以外の値を作成する操作はなく、操作は失敗しません。0
エリアケイガン

@EliahKaganは、欠陥を指摘してくれてありがとう。編集済み。
souravc

16

Bashはこの種の算術ではあまりうまくいきません...ここにあなたの問題があります:

$ echo $((1/5))
0
$ echo $((2/5))
0
$ echo $((4/5))
0
$ echo $((4/5))
0

非整数値を処理する必要がある場合は、使用できます bc

$ max=5; for e in $(seq 1 1 "$max"); do percent=$(bc <<< "scale=1 ; $e/$max*100") ; echo "echo $e / $max : = ${percent%.*}"; done
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

(出力を整数としてフォーマットする方法を指摘してくれた@Arronicalに感謝します)


私は間違いなくこれを見ていきます、もう一度ありがとう!
サイベックス

1
エコーを次のように.0変更すること$percentで、出力からトリムできます${percent%.*}:)
Arronical

11

bashとは異なり、awkは完全な浮動小数点演算を提供します。例えば:

$ awk -v max=5 'BEGIN{for (e=1;e<=max;e++) print "echo " e " / " max " : = " 100*e/max}' 
echo 1 / 5 : = 20
echo 2 / 5 : = 40
echo 3 / 5 : = 60
echo 4 / 5 : = 80
echo 5 / 5 : = 100

5

試してみる

percent=$(( $e*100/$max ))

:)

セクションの算術評価を参照してください。

man bash

整数のみをサポートしています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.