Bc (UNIX)

bcは、Unix環境で広く利用される任意精度演算プログラムであり、その入力言語でもあります。

概要



bcは、中置記法で記述された算術式を計算するために用いられます。式はコマンドライン引数や標準入力から与えることができ、例えば `(1 + 3) 2` を入力すると `8` と出力します。POSIX標準として定義されていますが、GNU版のように大幅な拡張が加えられた実装も存在します。Plan 9版は標準のスーパーセットであり、GNU版のサブセットという位置づけです。その他、オリジナルのUNIX版やOpenBSDプロジェクトによる実装が主要なものとして挙げられます。また、Windows用のバイナリも配布されています。

標準的な実装



bcは伝統的に、後置記法(逆ポーランド記法)を採用するdcというプログラムのフロントエンドとして実装されてきました。標準仕様もこの実装を考慮して定義されていますが、必ずしもこの構造に従う必要はありません。GNU版では、bcとdcはそれぞれ独立したプログラムとして実装されています。bcとdcを連携させる場合、どちらを親プロセスとするかは実装によって異なります。

言語要素



bcの言語要素には、1文字の変数名・配列名・関数名、一般的な演算子、C言語に似た制御構造(if文、whileループ、forループ)が含まれます。ただし、C言語とは異なり、if文にはelse節がありません。関数定義には`define`キーワード、戻り値には`return`キーワードを使用します。関数内の変数は`auto`キーワードで宣言し、局所変数として扱われます。全ての数値と変数は任意精度で扱われ、精度はグローバル変数`scale`で設定します。入力と出力の基数は、それぞれ`ibase`と`obase`で指定できます。計算結果を変数に格納しない場合、結果はそのまま出力されます。対話的な利用を想定しているため、文末には改行が必要です。コメントはC言語と同様に`/`と`/`で囲みます。

演算子



C言語と同じ演算子


bcでは、以下の演算子がC言語と同様の動作をします。

`+`, `-`, ``, `/`, `+=`, `-=`, `=`, `/=`, `++`, `--`, `<`, `>`, `==`, `!=`, `<=`, `>=`, `(`, `)`, `[`, `]`, `{`, `}`

C言語と類似する演算子


剰余演算子 `%` および `%=` は、グローバル変数`scale`が0に設定されている場合に限りC言語と同じ動作をします。`scale`が0より大きい場合、商を指定された精度で計算した値に除数を掛け、被除数から引いた値となります。

C言語と意味が異なる演算子


`^` および `^=` は、C言語ではビット単位の排他的論理和ですが、bcではべき乗演算子(指数は整数)として機能します。

C言語にあるがbcにない演算子


以下のビット演算子、ブーリアン演算子、比較演算子は標準には存在しません。

`&`, `|`, `^`, `&=`, `|=`, `^=`

`&&`, `||`, `^^`, `&&=`, `||=`, `^^=`

`<<`, `>>`, `<<=`, `>>=` , `?:`

組み込み関数



標準では、組み込み関数は`sqrt()`のみです。その他の関数は外部の標準ライブラリとして提供されます。

数学関数



`-l`オプションを指定すると、三角関数(正弦、余弦、逆正接)、自然対数指数関数、2引数のベッセル関数Jが利用可能になります。他の標準的な数学関数(逆正弦関数、逆余弦関数など)はこれらの関数を基に構築できます。`-l`オプションを使用すると、同時に`scale`が20に設定されるため、剰余演算の結果に注意が必要です。

Plan 9版



Plan 9版のbcは、標準版とほぼ同じですが、`print`文が追加されています。

GNU版



GNU版のbcは、多くの拡張機能を備えています。dcのフロントエンドではなく、独立したプロセスとして動作します。標準との互換性を保ちつつ、変数名、配列名、関数名に1文字以上の名前が使用可能であり、C言語の演算子やif文のelse節も利用できます。出力は、変数を介さず直接表示できるほか、`print`文で表示することも可能です。`read`文を利用して対話的に数値入力を受け付けることができます。コメントは、C言語スタイルのほか、`#`から行末まで記述できます。直近の計算結果は、組み込み変数`last`に格納されます。

追加された演算子


GNU版では、以下の論理演算子が追加されています。

`&&`

`||`

`!`

これらの演算子は、if文の条件式で使用できます。

関数



関数に関する仕様は、標準版と変わりません。

コード例



bcで浮動小数点数のべき乗を計算する関数例を以下に示します。標準のbcとGNU版で若干異なる記述が必要です。

標準のbcによるべき乗関数

bc
/ x の整数部分を返す関数 /
define i(x) {
auto s
s = scale
scale = 0
x /= 1 / x を丸める /
scale = s
return (x)
}

/ x^y == e^(ylog(x)) という性質を使う /
define p(x,y) {
if (y == i(y)) {
return (x ^ y)
}
return ( e( y l(x) ) )
}


GNU版のbcによるべき乗関数

bc

数の整数部分を返す関数


define int(number) {
auto oldscale
oldscale = scale
scale = 0
number /= 1 / 丸める /
scale = oldscale
return number
}

number^exponent == e^(exponentlog(number)) という性質を利用


define power(number,exponent) {
if (exponent == int(exponent)) {
return number ^ exponent
} else {
return e( exponent l(number) )
}
}


円周率の計算



bcを利用して円周率を計算する例を示します。
bash
bc -l -q
scale = 10000;
(12a(1/49)+32a(1/57)-5a(1/239)+12a(1/110443))4


C言語のコードの変換



bcの文法はC言語に似ているため、Cで書かれたアルゴリズムをbcに容易に移植できます。これにより、bcの任意精度演算の恩恵を受けることができます。

シェルスクリプトでの利用



bcは非対話的に利用でき、パイプやヒアドキュメントから入力を供給することができます。

例:
bash
result=$(echo "scale=2; 5 7 / 3;" | bc)
echo $result

または
bash
bc < scale=2
5 7 / 3
!


その他



数値の指数表記(例:1.23e-17)はサポートされていません。

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。