shellで浮動小数点の計算をする方法

2015年6月18日

Shell プログラミング

shellで普通に計算すると、どうしても整数で返ってくるため、少数値を扱うのに困ってしまいます。 ただ、浮動小数点を扱えない訳ではなく、特定のお作法を通してやる必要があるという事なんですね。 そこで、まあまあ簡単に少数値の計算を行える方法をご紹介します。

bcコマンドを使う

$ expr 2 - 1 > 1 $ expr 2.1 - 0.9 > expr: not a decimal number: '2.1' exprコマンドは整数専用なので、上記のように怒られてしまいます。 小数点も扱えるbcコマンドというのがあり、数値計算を行うコマンドです。 あまり使われることはないのですが、計算式において、色々と便利な機能を持っているので 使い慣れておくとかなり得することが多いでしょう。

小技

計算結果が1より少ない少数値の場合、.(ピリオド)の前が省略されるようです。 $ echo “1.1-0.9”|bc -l > .2 数値としては、整数の箇所にも0を付けたい場合は、awkを用いて以下のようにすることで対応可能になります。 $ echo “1.1-0.9”|bc -l|awk '{if($0~/^\./){print "0"$0}else{print $0}}' > 0.2 あれ?最初からawkでやればいいんでないか? 試しにやってみる $ echo "2.1 - 1.9"|awk '{print $1 - $3}' > 0.2 演算子を含めて処理できるbcもいいが、数字を直接操作できるawkも魅力ですね。 しかも、整数の0までしっかりついてるし・・・orz

速度比較

エンジニアとして少し気になったので、bcとawkの速度比較を行なってみました。 #!/bin/bash A=0 for i in `seq 0 10000`;do A=`echo $i+$A|bc -l` done echo $A #!/bin/bash A=0 for i in `seq 0 10000`;do A=`echo "$i $A"|awk '{print $1+$2}'` done echo $A #!/bin/bash A=0 for i in `seq 0 10000`;do A=$((A+i)) done echo $A

解説

0〜10000までの数値を累計で足し込んでいく式をbc版とawk版で書いてみました。 それでは、実行!

実行結果

$ sh bc.sh 50005000 real 0m29.457s user 0m12.210s sys 0m20.309s $ sh awk.sh 50005000 real 0m31.180s user 0m13.158s sys 0m21.239s $ sh kakko.sh 50005000 real 0m0.077s user 0m0.069s sys 0m0.008s

0〜1000の値に変更して再度実行

$ sh bc.sh 500500 real 0m2.886s user 0m1.222s sys 0m1.993s $ sh awk.sh 500500 real 0m3.253s user 0m1.362s sys 0m2.169s $ sh kakko.sh 500500 real 0m0.026s user 0m0.010s sys 0m0.012s

まとめ

ほんのチョビっとだけbcコマンドの方が早いようですね。 しかし、驚愕なのは二重括弧のスピード! 桁が2つ近くも違う。 確かにawkやbcと違って、他のモジュールを読み込んでいないのでネイティブ動作だけだからでしょう。 ちなみに、exprを使うのがセオリーのようですが、awkやbcと同じでしょうね。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。