Provided by: manpages-ja_0.5.0.0.20221215+dfsg-1_all
名称
bc - 任意精度の計算言語
書式
bc [ -hlwsqv ] [long-options] [ file ... ]
バージョン
このマニュアルは GNU bc version 1.06 について記述してあります。
解説
bc は、任意の精度の数値を扱う事ができ、プログラミング言語 C の文法に よく似た形の入力を対 話的に実行する言語です。 コマンドラインのオプションの指定により、標準数学ライブラリを使用 することも できます。これを指定した場合は、どのファイルを処理するよりも前に 数学ライブラリ が定義されます。 bc は動作を開始するとまず最初にコマンドラインで指定したファイルを 順に処 理します。すべてのファイルを処理した後は、bc は 標準入力からの読み込みを行います。すべての コードは、それが読み込ま れた時点で実行されていきます。(もし、ファイル中にプロセッサを止め る コマンドが含まれていた場合は、標準入力からの読み込みは行われません。) 本バージョンの bc は、伝統的な bc の実装および POSIX のドラフト規格よりも拡張されていま す。コマンドラインオプションにより、 これらの拡張に対して警告を表示したり拒絶したりするこ とが可能です。 本ドキュメントでは、このプロセッサが受理する言語について説明します。 拡張機 能についてはその旨明記します。 オプション -h, --help 使用方法を表示し、終了します。 -i, --interactive 対話モードを強制します。 -l, --mathlib 標準数学ライブラリを定義します。 -w, --warn POSIX bc に対する拡張機能が入力された場合は警告を出します。 -s, --standard POSIX bc の言語仕様に厳密に従って処理します。 -q, --quiet GNU bc 導入メッセージを表示しません。 -v, --version バージョン番号と著作権を表示して終了します。 数 bc における最も基本的な要素は `数' です。数は、整数部と小数部があり、 任意の精度をとること ができます。すべての数は、内部では 10 進数で表現されており、 計算も 10 進数で行われま す。(本バージョンでは、除算と乗算で結果に切捨てが 起こります。) 数には length と scale と いう 2 つの属性があります。 length は 10 進での有効桁数で、scale は小数点以下の 10 進での 有効桁数です。 例えば、 .000001 は、lengthが 6 で、scale も 6 です。 1935.000 は、lengthが 7 で、scale が 3 です。 変数 数は、単純変数と配列の 2 種類の変数に保存されます。単純変数と配列変数には共に 名前が付けら れます。この名前は、最初の 1 文字目がアルファベットで、後は、 アルファベット、数字およびア ンダスコアを任意の文字数組み合わせて 使うことができます。すべてのアルファベットは小文字で なければなりません。 (アルファベットと数字を使った名前の機能は拡張機能です。 POSIX bc で は、変数に英小文字 1 文字しか許されません。) 配列変数の名前には必ずブラケット ([]) がつく ので、変数の型は文脈において はっきりしています。 特殊な変数として scale, ibase, obase, last の 4 つの変数があります。 scale で計算時の小数 点以下の有効桁数を指定します。 scale のデフォルトは 0 です。 ibase と obase で入力および出 力の変換基数を指定します。 デフォルトでは、入力、出力の基数は共に 10 です。 last は、最後 に bc が出力した数を保持しています (これは拡張機能です)。これらについては、後で適切なとこ ろで詳しく説明します。 これらの変数には、式で使われる代入と同様の代入を行うことが可能で す。 コメント bc は、/* から */ の間をコメントとして扱います。 コメントはどこから始まっていてもよく、1 文字の空白として扱われます。 (これにより、コメントはその前後の入力アイテムを切り離しま す。たとえば、 変数名の途中にコメントを置くことはできません。) コメントの中にはいくつ改行 があってもかまいません。 bc をスクリプトとしても使えるようにするため、1 行コメントが 拡張機能として追加されまし た。1 行コメントは # で始まり、 次の改行まで有効です。その改行文字自体はコメントの一部とは みなされず、 普通に処理されます。 式 `数' は、式および文によって操作されます。 この言語は対話的になるように設計されているため、 文および式は可能な限り即座に実行されます。 "main" プログラムといったものはなく、そのかわ り、コードは それに出くわした時点で実行されます。 (後で述べる`関数'は、それに出くわした時 点で定義されます。) 式の最も単純なものは、ただの定数です。bc は、入力された 定数を、変数 ibase で指定される現 在の基数を元に、内部的には 10 進表現の 数に変換します。(関数の場合には例外があります。) ibase には、2 から 16 までが使用できます。 この範囲を越える値を ibase に代入しようとする と、 2 あるいは 16 を指定したことになります。 数の入力には、0-9 および A-F の文字が利用で きます。(注意: これは大文字でなければなりません。小文字は変数名です。) 1 桁の数は ibase の 値に関係なくその値を持ちます (すなわち A=10)。 複数桁の数の場合、bc は ibase 以上の値をも つすべての入力桁を ibase-1に変更します。これにより、数 FFF は常に、 その入力基数を使って 3 桁で表現可能な最大の値を表します。 すべての演算式が、他の多くの高級言語に似たものとなっています。 数の型は 1 種類しかないた め、型変換の規則はありません。 そのかわり、式の有効桁数に関する規則があります。 すべての式 に有効桁数があり、これはその被演算数の有効桁数と 施される演算、それに多くの場合、 変数 scale から決定されます。scale には、0 から C の整数で表現できる最大の値までが指定可能で す。 以下、bc で使用可能な演算子を説明します。なお、完全形の式を "expr"、 単純変数または配列変 数を "var" と表記します。 単純変数は単に name と表し、配列変数は name[expr] と表します。特に言及しない限り、結果の有効桁数は、注目している式の 最大有効桁数になりま す。 - expr 結果はその式の符号を反転したものとなります。 ++ var 変数を 1 だけインクリメントし、その新しい値が式の結果となります。 -- var 変数を 1 だけデクリメントし、その新しい値が式の結果となります。 var ++ 式の結果はその変数の値となり、それからその変数を 1 だけ インクリメントします。 var -- 式の結果はその変数の値となり、それからその変数を 1 だけ デクリメントします。 expr + expr 式の結果は 2 つの式の和となります。 expr - expr 式の結果は 2 つの式の差となります。 expr * expr 式の結果は 2 つの式の積となります。 expr / expr 式の結果は 2 つの式の商となります。 結果の scale は変数 scale の値となります。 expr % expr 結果は、以下のようにして求められる剰余です。a%b を求めるために、まず a/b を scale の有効桁数で計算します。この結果を用いて、a-(a/b)*b を、 scale+scale(b) と scale(a) の大きい方の有効桁数で計算します。 もし scale に 0 がセットされ、両方の式が整数であ れば、 整数の剰余が求められます。 expr ^ expr 式の結果は、1 番目の式の値を 2 番目の回数だけ乗じたものになります。 2 番目の式 は、整数でなければなりません。 (2 番目の式が整数でない場合は警告が表示され、 整数に 切り詰めた値が使用されます。) 結果の scale は、べき指数が 負なら scale になりま す。べき指数が正なら、 "1 番目の式の scale とべき指数との積" および "scale と 1 番 目の式の scale の大きい方" のうちの小さい方 (つまり、scale(a^b) = min(scale(a)*b, max( scale, scale(a)))) となります。 expr^0 は常に 1 を返します。 ( expr ) 標準の優先度を使わずに、この式の評価を優先します。 var = expr 式の値が変数に代入されます。 var <op>= expr "var" が一度しか評価されないこと以外は "var = var <op> expr" と同じです。 "var" が 配列の場合は動作が違うことがあり得ます。 関係演算は特殊な演算で、結果は常に 0 か 1 になります。関係が偽の時 0、 真の時 1 になりま す。関係演算は、演算式のどこでも使う事ができます。 (POSIX bcでは、関係演算は、if, while, for 文の中だけで、しかも 1 つの関係式しか使用できません。) 関係演算子は以下の通り。 expr1 < expr2 expr1 が expr2 より小さい場合 1 になります。 expr1 <= expr2 expr1 が expr2 より小さいか等しい場合 1 になります。 expr1 > expr2 expr1 が expr2 より大きい場合 1 になります。 expr1 >= expr2 expr1 が expr2 より大きいか等しい場合 1 になります。 expr1 == expr2 expr1 と expr2 が等しい場合 1 になります。 expr1 != expr2 expr1 と expr2 が等しくない場合 1 になります。 論理演算も使えます。(POSIX bc には論理演算はありません。) 論理演算も関係演算と同様、結果は 0 か 1 (各々偽および真) になります。 論理演算子は以下の通り。 !expr expr が 0 なら 1 になります。 expr && expr expr1 と expr2 が両方とも 0 でないなら、1 になります。 expr || expr expr1 と expr2 のどちらか一方が 0 でないなら、1 になります。 各演算子の優先順位と結合規則は次の通りです。 (最初のものほど低く、後にいくほど高い優先順位 で先に実行されます。) || (左から結合) && (左から結合) ! (結合せず) 関係演算 (左から結合) 代入演算 (右から結合) + - (左から結合) * / % (左から結合) ^ (右から結合) - (単項マイナス) (結合せず) ++ -- (結合せず) この優先順位は、POSIX bc のプログラムがそのまま正しく動くように 配慮して決められていま す。このため、関係演算と論理演算を 代入文と共に用いた場合、通常とは異なる振る舞いをしま す。 次の例を考えてみましょう: a = 3 < 5 C プログラマのほとんどは、 ``3 < 5'' の関係演算が実行された結果 (つまり 1) が変数 ``a'' に 代入される、 と考えるでしょう。 ところが bc では、まず 3 が変数 ``a'' に代入され、 それか ら 3 と 5 の比較が行われるのです。 この間違いを避けるために、 関係演算や論理演算を代入演算 と共に用いる場合は、 括弧を使うのが最良です。 bc には特別な式がさらにいくつか備わっています。 それはユーザ定義関数と標準関数に関するもの で、 すべて "name(parameters)" という形をしています。 ユーザ定義関数については関数の章を参 照して下さい。 標準関数は以下の通りです: length ( expression ) expression の有効桁数を返します。 read ( ) (拡張機能) 関数の出現位置に関係なく、標準入力から数を読み取ります。 データとプログ ラムの両方を標準入力から与えるような場合には、 問題を生じうることに注意して下さい。 最良の方法は、 ユーザからデータの入力の必要があるなら、プログラムはあらかじめ作って おき、 標準入力からプログラムを入力しないようにすることです。 read 関数の値は標準入 力から読み込んだ数です。 その際、変換基数として変数 ibase の現在の値が用いられま す。 scale ( expression ) expression の小数点以下の有効桁数を返します。 sqrt ( expression ) expression の平方根を返します。 expression に負の値を指定した場合は、ランタイムエ ラーになります。 文 文は (ほとんどの算術言語がそうであるように)、処理を順番に実行していく単位です。 bc では文 は「できるだけ早い段階で」実行されます。 改行が入力された時点で、実行可能な文が存在してい れば、即座に実行します。 このため bc では改行が重要な役割を持っています。 実際、セミコロン と改行が文の区切りとして使用されます。 不適当な場所で改行を入力すると、文法エラーになりま す。 改行は文の区切りですが、バックスラッシュを用いて改行を隠すことができます。 bc にとっ て、"\<nl>" (<nl>は改行) は改行ではなく空白に見えます。 文のリストは、セミコロンと改行で区 切られた文の並びです。 以下、bc の文の種類とその動作について説明します。 (なお、以下の説明 で ([]) で括った部分は省略可能な項です。) 演算式 演算式には次の 2 つの種類があります。 演算式が "<variable> <assignment> ..." で始 まっていれば、 それは代入文として扱われます。 そうでなければ、演算式は評価されて出 力に表示されます。 結果が表示された後、改行が表示されます。 例えば、"a=1" は代入文 であり、 "(a=1)" は代入文が埋め込まれた演算式です。 表示される数値はすべて、変数 obase で決まる基数で表示されます。 obase に指定できる値は 2 から BC_BASE_MAX までで す。 (「制限」の章を参照。) 基数 2 から 16 まででは、通常の数表記法が用いられます。 基数が 16 より大きい場合、bc は、 各桁を 10 進表記する複数桁文字表記法で表示しま す。 複数桁文字表記法では、各桁は空白で区切られます。 各桁は "obase-1" を 10 進で表 記するのに必要な桁数の数字から成ります。 数の精度は任意に選べるため、数によっては 1 行に表示できない場合もあります。 そのような長い数は、行末に "\" を付けて次行に継続 します。 1 行に表示できる文字数は 70 です。 bc の対話的性質により、ある数を表示する と、 表示した値が特殊変数 last に代入されるという副作用が生じます。 ユーザはタイプ し直すことなく最後に表示された値を再利用できます。 last に値を代入することも可能 で、 その場合、前回表示された値が代入値で上書きされます。 新しく代入した値は、次に 数が表示されるか別の値が last に代入される まで有効です。(bc の実装によっては、 数 の一部になっていない単一のピリオド (.) を last の短縮表記として 用いることができま す。) string 文字列 string が出力に表示されます。 文字列は二重引用符で始まり、次の二重引用符まで のすべての文字を含みます。 改行を含め、すべての文字は文字通りに解釈されます。 文字 列の後に改行は出力されません。 print list print 文 (これは拡張機能です) は、もうひとつの出力方法です。 "list" はコンマで区 切った文字列および演算式のリストであり、 各文字列あるいは演算式がリストの順に表示さ れます。 最後に改行は出力されません。 演算式は評価され、その値が表示されるととも に、 変数 last に代入されます。 print 文中の文字列は出力に表示されますが、特殊文字 を含めることができます。 特殊文字はバックスラッシュ (\) で始まります。 bc で使える 特殊文字は、 "a" (ベル)、"b" (バックスペース)、 "f" (フォームフィード)、"n" (改 行)、"r" (復帰)、"q" (二重引用符)、 "t" (タブ)、"\" (バックスラッシュ) です。 これ 以外は無視されます。 { statement_list } 複文です。複数の文を 1 つのグループにまとめて実行します。 if ( expression ) statement1 [else statement2] if 文は演算式 expression を評価し、その値に応じて 文 statement1 または文 statement2 を実行します。 expression の値が 0 でなければ statement1 が実行されます。 statement2 が存在し、expression の値が 0 ならば、statement2 が実行されます。 (else 節は拡張機能です。) while ( expression ) statement while 文は expression が 0 でない間、繰り返し statement を実行します。 statement の 実行前に毎回 expression を評価します。 expression の値が 0 になるか、break 文を実行 すると、 ループが終了します。 for ( [expression1] ; [expression2] ; [expression3] ) statement for 文は statement の繰り返し実行を制御します。 expression1 はループ実行の前に評価 されます。 expression2 は statement の実行前に毎回評価され、 その値が 0 でなければ statement が実行されます。 expression2 の値が 0 になると、ループは終了します。 各 statement 実行の後、再び expression2 が評価される前に expression3 が 評価されます。 expression1 あるいは expression3 が省略されていると、 そこでは何も評価されません。 expression2 が省略されている場合、expression2 が 1 であるのと 同様に扱われます。 (各 expression が省略可能なのは拡張機能です。 POSIX bc では、3 つの expression はど れも省略できません。) 以下は for 文と等価なコードです: expression1; while (expression2) { statement; expression3; } break それを含む最も内側の while もしくは for 文による繰り返しを強制的に中断します。 continue それを含む最も内側の for 文における次の繰り返しに進みます。 (continue 文は拡張機能 です) halt 実行されると bc プロセッサを終了させます(拡張機能)。 例えば "if (0 == 1) halt" の場 合は bc は終了しません。 halt 文が実行されないからです。 return 関数から戻ります。関数の結果は 0 になります。(関数の章を参照) return ( expression ) 関数から戻ります。関数の結果は expression になります。(関数の章を参照) 拡張機能です が、括弧は必須ではありません。 疑似文 これらは今までの文とは動作が異なります。 疑似文は実行文ではなく、「コンパイル」時点で処理 されます。 limits bc のローカルバージョンにより制限される限界値を表示します。 (limits は拡張機能です) quit bc を終了します。どんな場所にあっても、quit 文は 入力された時点で実行されます。例え ば、 "if (0 == 1) quit" という記述であっても、bc は終了します。 warranty 保証に関する注意を長めに表示します。 (warranty は拡張機能です) 関数 関数は、後で実行されるべき計算手順を定義する機能です。 bc の関数は常に値を計算し、それを呼 びだし側に返します。 関数定義は、それが入力から読み込まれた時点で定義が行われるという点で 「ダイナミック(動的)」です。 一度定義された関数は、同じ名前で別の関数が定義されるまで使用 可能で、 新しい関数が定義された場合は、前の関数が置き換えられます。 関数の定義は、以下のよ うに行います: define name ( parameters ) { newline auto_list statement_list } 関数呼び出しは、 "name(parameters)" という形式の演算式です。 パラメータ parameters は数あるいは配列 (拡張機能) です。 関数定義では、0 あるいは 1 個以上 のパラメータ名を コンマで区切って並べることで定義します。 数は値渡し(call by value)でのみ 渡され、配列は変数渡し(call by variable)で のみ渡されます。 配列はパラメータ定義中で "name[]" のように表記して指定します。 関数呼び出しでは、数のパラメータに対して完全な演算式 の実パラメータを 記述します。 配列を渡す表記は配列パラメータ定義と同様です。 名前付き配列 は変数(variable)によって関数に渡されます。 関数定義はダイナミックゆえ、 パラメータの数と型 は関数呼び出しの際にチェックされます。 パラメータの数あるいは型に何らかの不整合があると、 ランタイムエラーが発生します。 未定義関数を呼び出した場合もランタイムエラーとなります。 auto_list は省略可能で、ローカル変数として使用する変数のリスト です。auto_list が存在する なら、その文法は "auto name, ... ;" となります。(セミコロンは省略可能です。) 各 name が ローカル変数の名前となります。 配列はパラメータと同様の表記で指定できます。 これらの変数 は、関数の最初でその値がスタックにプッシュされたのち 値 0 に初期化され、関数の実行中に使用 されます。 これらの変数は関数出口にてポップされ、 (関数呼び出し時の)元の値が復元されます。 パラメータは実際にはローカル変数であり、 関数呼び出しで与えられた値に初期化されます。 bc のローカル変数は伝統的な意味でのローカル変数と異なり、 関数 A が関数 B を呼び出しているよ うな場合、関数 B の中に 関数 A のローカル変数と同じ名前のローカル変数がない限り、 関数 A のローカル変数名をそのまま使って、 関数 B から関数 A のローカル変数をアクセスできます。 ローカル変数とパラメータはスタックにプッシュされるため、 bc は再帰的な関数呼び出しをサポー トしています。 関数本体は bc の文のリストです。 繰り返し述べますと、文はセミコロンか改行で区切られていま す。 return 文により関数は終了し、値を返します。 return 文には 2 つの形式があり、 ひとつめ の形式 "return" は、呼び出し元に値 0 を返します。 もうひとつの形式 "return ( expression )" は、 expression の値を計算し、それを呼び出し元に返します。 各関数の最後には "return (0)" があるものと解釈されます。 これにより、明示的に return 文を置かなくても、 関数は終了して値 0 を返します。 関数の中では、変数 ibase の動作が変わります。関数の中で使われて いる定数は、関数の呼びだし 時点の ibase を元に変換が行われます。 このため、関数内部で ibase を変更しても無視されま す。ただし、標 準関数 read を呼び出した場合は例外で、これは常に現在の ibase の値をもとに変 換が行われます。 拡張機能ですが、定義の書式が若干緩やかになりました。 標準では、開くブレースが define キー ワードと同じ行にあることと、 他の部分が引き続く行にあることが必須です。 本バージョンの bc では、関数の開くブレースの前後の改行数は任意です。 例えば、次の定義は合法です。 define d (n) { return (2*n); } define d (n) { return (2*n); } 数学ライブラリ bc に -l オプションを付けて起動した場合は、数学ライブラリが 読み込まれ、デフォルトの scale が 20 に設定されます。 数学関数は、それを呼び出した時点の scale の値に従って計算を行いま す。 数学ライブラリによって使用可能になる関数は、次の通りです: s (x) sin (x の単位はラジアン) c (x) cos (x の単位はラジアン) a (x) atan (返り値の単位はラジアン) l (x) log (自然対数) e (x) exp (指数関数) j (n,x) 整数 n 次のベッセル関数 使用例 次の例は、/bin/sh でシェル変数 pi に ``パイ'' の値を代入します。 pi=$(echo "scale=10; 4*a(1)" | bc -l) 次の例は、数学ライブラリで使われている ``e (x)'' の定義です。 この関数は POSIX bc で記述さ れています。 scale = 20 /* Uses the fact that e^x = (e^(x/2))^2 When x is small enough, we use the series: e^x = 1 + x + x^2/2! + x^3/3! + ... */ define e(x) { auto a, d, e, f, i, m, v, z /* Check the sign of x. */ if (x<0) { m = 1 x = -x } /* Precondition x. */ z = scale; scale = 4 + z + .44*x; while (x > 1) { f += 1; x /= 2; } /* Initialize the variables. */ v = 1+x a = x d = 1 for (i=2; 1; i++) { e = (a *= x) / (d *= i) if (e == 0) { if (f>0) while (f--) v = v*v; scale = z if (m) return (1/v); return (v/1); } v += e } } 次の例は、bc の拡張機能を使って、``checkbook balances'' (小切手帳残高) を計算する簡単なプ ログラムです。 このプログラムをファイルにしておくと、 毎回タイプしなおさずに何度も使うこと ができます。 scale=2 print "\nCheck book program!\n" print " Remember, deposits are negative transactions.\n" print " Exit by a 0 transaction.\n\n" print "Initial balance? "; bal = read() bal /= 1 print "\n" while (1) { "current balance = "; bal "transaction? "; trans = read() if (trans == 0) break; bal -= trans bal /= 1 } quit 次の例は、再帰呼び出しにより階乗を計算する関数です。 define f (x) { if (x <= 1) return (1); return (f(x-1) * x); } readline と libedit のオプション GNU bc は (configure のオプションによって) GNU readline 入力エディタライブラリまたは BSD libedit ライブラリ を使うようにコンパイルできます。 これは、bc に入力する前に、行の編集を 可能にします。 以前に入力した行のヒストリも利用可能になります。このオプションで コンパイル された bc では、さらに 1 つの特殊な変数 history が追加され、ヒストリに保存される行の数を指 定します。 readline では、 その値が -1 (デフォルト値)なら、ヒストリ行は制限なく保存されま す。 正の数を指定すると、ヒストリ行がその数に制限されます。 0 ならヒストリ機能が無効になり ます。 デフォルト値は 100 です。 詳しくは、ユーザマニュアルの GNU readline と history ライ ブラリと BSD libedit をご覧下さい。 readline と libedit の両方を同時に有効化できません。 相違点 このバージョンの bc は POSIX P1003.2/D11 ドラフトから実装されており、 そのドラフトや以前の 実装に比べていくつかの相違点や拡張点があります。 伝統的に行われていたような dc(1) を用いた 実装ではありません。 このバージョンは単一プロセスであり、 プログラムをバイトコードに変換し たものを解析して実行します。 「ドキュメントに記載されていない」オプション (-c) があり、 プ ログラムを実行する代わりに、それをバイトコードに変換した結果を 標準出力に出力します。 これ は主として、パーザのデバッグと数学ライブラリの準備に用いられました。 主な相違点は拡張機能によるものです。 機能を高めたり追加したりするために機能が拡張された り、 新機能が追加されたりしています。 相違点と拡張点のリストを以下に示します。 LANG このバージョンは、 環境変数 LANG および LC_ で始まるすべての環境変数の処理に関して POSIX 標準に 準拠していません。 名前 伝統的な bc および POSIX bc は、関数、変数、配列の名前として単一の文字を使います。 このバージョンでは、 先頭が文字で始まり、文字と数字とアンダースコアで 構成される 2 文字以上の名前が使えるように拡張されています。 文字列 文字列には NUL 文字を含むことはできません。 POSIX では、文字列にはあらゆる文字を含 めることができなければならない、 としています。 last POSIX bc には変数 last はありません。 bc の実装によっては、last と同じ意味で ピリオ ド (.) を用いるものがあります。 比較 POSIX bc では、比較は if 文、while 文、for 文の第 2 式の中でのみ 用いることができま す。 また、これらの文の中ではただ 1 つの関係演算しか使えません。 if 文, else 節 POSIX bc には else 節はありません。 for 文 POSIX bc では for 文の各演算式は省略できません。 &&, ||, ! POSIX bc には論理演算子はありません。 read 関数 POSIX bc には read 関数はありません。 print 文 POSIX bc には print 文はありません。 continue 文 POSIX bc には continue 文はありません。 return 文 POSIX bc では、return 文の周りに括弧が必要です。 配列パラメータ POSIX bc では (現在のところ) 配列パラメータは完全には使えません。 POSIX の文法で は、関数定義では配列を使えますが、実際に呼び出すときの パラメータに配列を指定するこ とができません。(これはおそらく、文法上の 見落としでしょう。) 伝統的な bc の実装で は、配列パラメータは値渡し のみでした。 function format POSIX bc では、開くブレースが define キーワードと同じ行にあり、 auto 文が次の行にあ ることが必要です。 =+, =-, =*, =/, =%, =^ POSIX bc ではこれらの「旧式」の代入演算子を定義する必要はありません。 このバージョ ンではこれらの「旧式」代入演算子が使えるかも知れません。 limits 文を使って、インス トールしたバージョンがこれらをサポートしているか どうか、確かめてみて下さい。 もし そのバージョンが「旧式」代入演算子をサポートしていれば、 文 "a =- 1" は a に値 -1 を代入する代わりに a を 1 減じます。 数字表記中の空白 他の bc 実装では、数字表記の中に空白を含めることが許されます。 例えば、"x=1 3" は変 数 x に値 13 を代入します。 このバージョンの bc では、先の文は文法エラーになりま す。 エラーと実行 このバージョンの bc は、 プログラムに文法上のエラーや他のエラーが見つかった場合に どういうコードが実行されるか、 という点で、他の実装と異なっています。 ある関数定義 中で文法エラーが見つかると、 エラー回復機構は文の先頭を見つけて関数のパーズを続けよ うと努力します。 ひとたび関数の中で文法エラーが見つかると、 その関数は呼び出せなく なり、未定義状態となります。 対話的実行コードで文法エラーがあると、 現在の実行ブ ロックが無効になります。 実行ブロックとは、ひと続きの完全な文のあとの行末までのこと です。 例えば、次のコード a = 1 b = 2 には 2 つの実行ブロックがあり、 { a = 1 b = 2 } には 1 つの実行ブロックがあります。 ランタイムエラーが発生すると、現在の実行ブロックの実行 が終了します。 ランタイムの警告が発生しても、現在の実行ブロックは終了しません。 割り込み 対話セッションの間、SIGINT シグナル (通常、端末からの Control-C 入力で 発生します) によって現在の実行ブロックの実行が中断され、 どの関数が中断されたかを示す「ランタイ ム」エラーが表示されます。 ランタイムのデータ構造をすべてクリアした後メッセージが表 示され、 bc は次の入力を受け付ける状態になったことを示します。 これまでに定義した関 数はすべて定義されて残っており、 ローカルでない変数の値は割り込み発生時点の値のまま になっています。 ローカル変数と関数パラメータはすべて、クリア処理によって消去されま す。 非対話セッションでは、SIGINT シグナルで bc の実行全体が終了します。 限界 以下の項目が現在の bc プロセッサの限界値となっています。 このうちいくつかは、インストール 時に変更できます。 実際の値を得るには limits 文を使って下さい。 BC_BASE_MAX 現在のところ、出力の基数の最大値は 999 に設定されています。 入力側の基数の最大値は 16 です。 BC_DIM_MAX 現在のところ 65535 として配布されていますが、 インストールしたバージョンでは異なっ ているかも知れません。 BC_SCALE_MAX 小数点以下の桁数は INT_MAX 桁に制限されています。 また、小数点より上の桁数も INT_MAX 桁に制限されています。 BC_STRING_MAX 文字列中の文字数は INT_MAX 文字に制限されています。 指数 累乗演算 (^) の指数の値は LONG_MAX に制限されています。 変数名 単純変数、配列、関数各々について、一意に識別される名前は 32767 個に 制限されていま す。
環境変数
bc は以下の環境変数を解釈します。 POSIXLY_CORRECT -s オプションと同じです。 BC_ENV_ARGS これは bc に引数を渡す別の方法で、コマンドライン引き数と 同じ書式です。この引数が最 初に処理されるので、この環境変数で 指定されたファイルはコマンドライン引数で指定され たファイルよりも 先に処理されます。これにより、毎回 bc を呼び出すごとに 処理する「 標準の」オプションやファイルを設定できます。この環境変数で 指定するファイルには、bc を走らせるたびに定義しておきたいような 関数の定義を書いておくとよいでしょう。 BC_LINE_LENGTH 数字を出力するときの 1 行の文字数を整数で指定します。 数字が長過ぎると、バックス ラッシュと改行を含めた出力となります。
診断
コマンドラインで指定したファイルがオープンできない場合、 bc はファイルが利用できない旨を表 示して終了します。 また、コンパイル時あるいはランタイムの診断メッセージもありますが、 それ らは自身で理解できるようになっているはずです。
バグ
エラーリカバリがまだうまくいっていません。 バグ報告は、 bug-bc@gnu.org に電子メールでお願いします。 単語 ``bc'' を ``Subject:'' フィールドのどこかに入れておいてください。
作者
Philip A. Nelson philnelson@acm.org
謝辞
実装をテストする際に 広範囲に手助けしてくれた Steve Sommars (Steve.Sommars@att.com) に感謝 します。 たくさんの素晴らしい意見をもらいました。 彼のおかげでとてもよいものになりました。 . bc(1)