重要なポイント
- Linux Bash シェルは整数演算のみをサポートしており、浮動小数点数の計算を実行できません。
- Linux の bc ユーティリティを使用すると、シェル スクリプトで対話形式で高精度の浮動小数点計算を行うことができます。
- bc を使用すると、表示する小数点以下の桁数を設定し、標準数学ライブラリの関数を使用するなど、任意の精度で計算を実行できます。
Linux Bash シェルは整数演算のみをサポートします。浮動小数点計算を理解することも、それに対処することもできません。 bc ユーティリティを使用すると、シェル スクリプトで対話形式で高精度の浮動小数点計算を行うことができます。
Bash が整数のみをサポートする理由
Unix Bourne シェルを 整数演算に制限するという元の設計上の決定は、整数を RAM の 1 バイトにマッピングする初期の計算に根ざしている 可能性があります 。その決定の背後に何があったのか、私たちは決して知ることはできないかもしれません。さらに言えば、Bourne シェルの Linux 版である Bash シェルがなぜこれに倣うことにしたのかもわかりません。
Bash 自体は浮動小数点数の計算を実行できず、答えに小数部分が含まれる整数の計算は切り捨てられた整数値として報告されます。これは、コマンド ラインと Bash シェル スクリプトに当てはまります。ユースケースによっては、これが問題を引き起こしたり、重大な問題を引き起こしたりする可能性があります。
Linux には、浮動小数点計算を実行できる 2 つのユーティリティ アプリケーションが付属しています。その 1 つが DC です。これは少し珍しいもので、 逆ポーランド語表記 と同じように動作します。もう 1 つのツールは bc です。これは対話的に使用することも、コマンドとして使用することもでき、ここで説明する解決策です。
問題
Bash に 6 を 3 で割ってもらいましょう。
echo $(( 6 / 3 ))
予想通りの 2 つの答えが得られました。では、6 を 7 で割ってみましょう。明らかに、その答えは端数になります。
echo $(( 6 / 7 ))
ゼロは明らかに間違っています。もう一度、16 を 7 で割ってみましょう。
echo $(( 16 / 7 ))
答えは 2 です。何が起こっているのかというと、答えの小数部分が破棄されるため、答えは切り捨てられます。最初の例には小数部分がなかったので、正しい答えが得られます。
2 番目の例では、答えに整数要素はなく、小数部分のみが含まれていました。小数部分が切り捨てられているため、表示される答えはゼロです。
3 番目の例では、7 は 16 に 2 回除算され、小数点以下の剰余が生じます。ここでも、剰余は破棄され、結果は切り捨てられます。
bc を対話的に使用する
「bc」と入力して「Enter」キーを押すと、bc を対話型電卓として使用できます。
bc
bc アプリケーションが起動し、そのバージョン番号を通知して、入力を待ちます。計算を入力して「Enter」を押すと、bc が計算を評価して答えを表示します。
16 * 4
1024 / 32
2^2 * 1024
「Ctrl+L」を使用して画面をクリアし、「Ctrl+D」を使用してプログラムを終了できます。答えに小数部分が含まれる計算を試してみましょう。
22 / 7
それは私たちが期待していたものではありませんでした。直感に反しますが、bc では任意の精度を使用できますが、デフォルトでは小数点もそれに続く数字も表示されません。
本当の答えを表示するには、表示する小数点以下の桁数を bc に伝える必要があります。これを「scale」コマンドで行います。小数点以下 7 桁を求めて、計算をやり直します。
scale=7
22 / 7
ついに、私たちはどこかに到着しました。 「スケール」設定は、変更するまでそのまま残ります。小数点以下の桁数を設定すると、表示する 最大 桁数が bc に通知されます。回答にそれほど多くの小数点以下の桁数が必要ない場合は、必要な小数点以下の桁数が表示され、それ以上の桁数は表示されません。意味のないゼロが埋め込まれることはありません。
scale=10
0 .300003 * 0 .5
セミコロン「;」を使用すると、異なる計算を同じ行にリストできます。それらを分離するために。答えは、通常どおり、計算がリストされた順序で 1 行ごとに表示されます。
25 * 6; 12 .5 + 45 .001 ; 3 + 5 + 7 + 9
リストに「scale」コマンドを含めることもできます。
scale=8; 22 / 7; scale=3; 0.3 * 0.071
標準数学ライブラリ
-l (標準数学ライブラリ) オプションを使用すると、bc は一連の関数をロードし、「スケール」を小数点以下 20 桁に設定します。
bc -l
22 / 7
標準ライブラリをロードすると、計算でこれらの関数を使用できるようになります。
- s (x) : x の正弦
- c (x) : x のコサイン。
- a (x) : x の逆正接
- l (x) : x の自然対数
- e (x) : 値 x に対する e の指数
- j (n,x) : x の整数次数 n のベッセル関数。
サイン、コサイン、アークタンジェントではラジアン値が使用されます。
s (1 .1 )
c ( .891207 )
a ( .628473 )
コマンドラインで bc に入力を送信する
リダイレクトとパイプを使用して入力を bc に送信できます。入力を処理し、ターミナル ウィンドウに回答を表示します。
-l (標準数学ライブラリ) オプションの有無にかかわらず、bc にリダイレクトできます。
bc <<< 22/7
bc -l <<< 22/7
入力を bc にパイプするには、入力が別のプロセスの出力である必要があります。これにはechoを使うと便利です。
echo 22 / 7 | bc
echo 22 / 7 | bc -l
入力にスペースが含まれている場合、または「scale」コマンドを含めたい場合は、入力を引用符で囲みます。
echo "22 / 7" | bc -l
echo "scale=6; 22 / 7" | bc
Bash シェル スクリプトでの bc の使用
これで、bash スクリプトで浮動小数点計算を選択した精度で実行できるようにするために必要なものがすべて揃いました。スクリプトのパラメーターなど、 計算で Bash 変数を 参照することもできます。
これがスクリプトの例です。このテキストをエディタにコピーし、「pi.sh」として保存し、エディタを閉じます。
#!/bin/bash
first_number=22
second_number=7
pi=$( echo "scale= $1 ; $first_number / $second_number " | bc)
echo "Pi to $1 decimal places is: $pi "
2 つの数値を保持するには、「first_number」と「second_number」という 2 つの変数を使用します。これらの変数は、bc にパイプする入力で使用します。
また、スクリプトに渡される最初のコマンド ライン パラメーター「$1」を、「scale」を設定する値として使用しました。
スクリプトを試す前に、chmod で実行可能にする必要があります。
chmod + x pi .sh
さまざまなコマンドライン値を使用してスクリプトを試してみましょう。
./pi.sh 5
./pi.sh 14
./pi.sh 20
スクリプトのコマンドラインで指定した数の場所に pi が表示されます。
すべてを合計すると
Bash の整数のみの数学の制限を超えることで、スクリプトの精度と精度が向上します。
スクリプト内で echo を使用して入力を bc にパイプするのは少し面倒ですが、完全にうまく機能し、それだけの価値のある利点があります。





