Bashシェルスクリプトで浮動小数点計算(答えが小数となる除算)

2019-03-09Bash, CentOS, Cygwin, Linux, Ubuntu

Bashの組み込みの数値演算機能では、少数が取り扱えません。

$ X=10
$ Y=2
$ Z=4
# こちらは問題ない
$ echo $(($X/$Y))
5
# こちらの結果がおかしい
$ echo $(($X/$Z))
2

echo $(($X/$Z)) の実行結果は 2.5 となってほしいが、小数点以下が切り捨てられてしまいます。

対処方法はいくつかあります。

bc コマンド を使う

# このままだと変わりなし
$ bc <<< "$X/$Z"
2
# 少数第何位まで計算するかを指定
$ bc <<< "scale=4; $X/$Z"
2.5000
$ # 無限循環小数
$ bc <<< "scale=4; $X/3"
3.3333

問題は scale の値をいくつにするかを予め知っておかないといけないこと。
卵が先か、鶏が先か。

bc -l でもっとよしなにしてくれるようです。

$ bc -l <<< "$X/$Z"
2.50000000000000000000
$ bc -l <<< "$X/3"
3.33333333333333333333

割り切れたのかどうなのかわかりませんね。

awk コマンドを使う

awk 最強伝説。

$ awk "BEGIN { print $X/$Z }"
2.5
# 循環小数が何故切れたのかは不明
$ awk "BEGIN { print 10/3 }"
3.33333

循環小数はなぜ切れた。

Bashの組み込み機能を使う

巡り巡ってきて、この方法が一番簡単何じゃないかと思いました。
実は $(( ... )) の公文で少数計算ができます。

# こちらは整数の演算
echo $(($X/$Z))
# こちらは少数の演算
echo $((1.0*$X/$Z*1.0))

2019-03-09Bash, CentOS, Cygwin, Linux, Ubuntu