aboutsummaryrefslogtreecommitdiff
path: root/ja_JP.eucJP/man/man1/bc.1
blob: c1f9c36b0836f7390864072102f3790339eaeb5b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
.\"
.\" bc.1 - the *roff document processor source for the bc manual
.\"
.\" This file is part of bc written initially for MINIX.
.\" Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
.\"
.\" This program is free software; you can redistribute it and/or modify
.\" it under the terms of the GNU General Public License as published by
.\" the Free Software Foundation; either version 2 of the License , or
.\" (at your option) any later version.
.\"
.\" This program is distributed in the hope that it will be useful,
.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
.\" GNU General Public License for more details.
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with this program; see the file COPYING.  If not, write to
.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
.\"
.\" You may contact the author by:
.\" e-mail: phil@cs.wwu.edu
.\" us-mail: Philip A. Nelson
.\" Computer Science Department, 9062
.\" Western Washington University
.\" Bellingham, WA 98226-9062
.\"
.\" %Id: bc.1,v 1.3.2.1 1996/11/06 09:23:50 phk Exp %
.\" jpman %Id: bc.1,v 1.3 1997/07/26 10:23:05 konuma Stab %
.\"
.TH bc 1 .\" "Command Manual" v1.03 "Nov 2, 1994"
.SH 名称
bc - 任意精度の計算言語
.SH 書式
\fBbc\fR [ \fB-lws\fR ] [ \fI file ...\fR ]
.SH バージョン
このマニュアルは GNU bc version 1.03 について記述してあります。
.SH 解説
\fBbc\fR は、任意の精度の数値を扱う事ができ、プログラミング言語 C の文法に
よく似た形の入力をインタラクティブに実行する言語です。
コマンドラインのオプションの指定により、標準数学ライブラリを使用することも
できます。これを指定した場合は、どのファイルを処理するよりも前に
数学ライブラリが定義されます。
\fBbc\fR は動作を開始するとまず最初にコマンドラインで指定したファイルを
順に処理します。全てのファイルを処理した後は、\fBbc\fR は
標準入力からの読み込みを行います。全てのコードは、それが読み込ま
れた時点で実行されていきます。(もし、ファイル中にプロセッサを止める
コマンドが含まれていた場合は、標準入力からの読み込みは行われません。)
.PP
本バージョンの \fBbc\fR は、伝統的な \fBbc\fR のインプリメントおよび POSIX
のドラフトよりも拡張されています。コマンドラインオプションにより、
これらの拡張に対して警告を表示したり拒絶したりすることが可能です。
本ドキュメントでは、このプロセッサが受理する言語について説明します。
拡張機能についてはその旨明記します。
.SS オプション
.IP -l
標準数学ライブラリを定義します。
.IP -w
POSIX \fBbc\fR に対する拡張機能が入力された場合は警告を出します。
.IP -s
POSIX \fBbc\fR の言語仕様に従って、厳密に処理します。
.SS 数
\fBbc\fR における最も基本的な要素は `数' です。数は、整数部と小数部があり、
任意の精度をとることができます。全ての数は、内部では 10 進数で表現されており、
計算も 10 進数で行われます。(本バージョンでは、除算と乗算で結果に切捨てが
起こります。) 数には length と scale という 2 つの属性があります。
length は 10 進での有効桁数で、 scale は小数点以下の 10 進での有効桁数です。
例えば、
.nf
.RS
 .000001 は、lengthが 6 で、scale も 6 です。
 1935.000 は、lengthが 7 で、scale が 3 です。
.RE
.fi
.SS 変数
数は、単純変数と配列の 2 種類の変数に保存されます。単純変数と配列変数には共に
名前が付けられます。この名前は、最初の 1 文字目がアルファベットで、後は、
アルファベット、数字およびアンダスコアを任意の文字数組み合わせて
使うことができます。全てのアルファベットは小文字でなければなりません。
(アルファベットと数字を使った名前の機能は拡張機能です。
POSIX \fBbc\fR では、変数に英小文字 1 文字しか許されません。)
配列変数の名前には必ずブラケット ([]) がつくので、変数の型は文脈において
はっきりしています。
.PP
特殊な変数として \fBscale, ibase, obase, last\fR の 4 つの変数があります。
\fBscale\fR で計算時の小数点以下の有効桁数を指定します。
\fBscale\fR のデフォルトは 0 です。
\fBibase\fR と \fBobase\fR で入力および出力の基数を指定します。
デフォルトでは、入力、出力の基数は共に 10 です。
\fBlast\fR は、最後に \fBbc\fR が出力した数を保持しています
(これは拡張機能です)。これらについては、後で適切なところで詳しく説明します。
これらの変数には、式で使われる代入と同様の代入を行うことが可能です。
.SS コメント
\fBbc\fR は、\fB/*\fR から \fB*/\fR の間をコメントとして扱います。
コメントはどこから始まっていてもよく、1 文字の空白として扱われます。
(これにより、コメントはその前後の入力アイテムを切り離します。たとえば、
変数名の途中にコメントを置くことはできません。)
コメントの中にはいくつ改行があってもかまいません。
.SS 式
`数' は、式および文によって操作されます。
この言語はインタラクティブになるように設計されているため、
文および式は即座に実行されます。
"main" プログラムといったものはなく、そのかわり、コードは
それに出くわした時点で実行されます。
(後で述べる`関数'は、それに出くわした時点で定義されます。)
.PP
式の最も単純なものは、ただの定数です。\fBbc\fR は、入力された
定数を、変数 \fBibase\fR で指定される現在の基数を元に、内部的には 10 進表現の
数に変換します。(関数の場合には例外があります。)
\fBibase\fR には、2 から 16 (F) までが使用できます。
この範囲を越える値を \fBibase\fR に代入しようとすると、
2 あるいは 16 を指定したことになります。
数の入力には、0-9 および A-F の文字が利用できます。(注意:
これは大文字でなければなりません。小文字は変数名です。)
1 桁の数は \fBibase\fR の値に関係なくその値を持ちます (すなわち A=10)。
複数桁の数の場合、\fBbc\fR は ibase 以上の値をもつ全ての入力桁を
\fBibase\fR-1に変更します。これにより、数 \fBFFF\fR は常に、
その入力基数を使って 3 桁で表現可能な最大の値を表します。
.PP
全ての演算式が、他の多くの高級言語に似たものとなっています。
数の型は 1 種類しかないため、型変換の規則はありません。
そのかわり、式の有効桁数に関する規則があります。
全ての式に有効桁数があり、これはその被演算数の有効桁数と
変数 \fBscale\fR から決定されます。\fBscale\fR には、0 から
C の整数で表現できる最大の値までが指定可能です。
.PP
以下、bc で使用可能な演算子を説明します。なお、完全形の式を "expr"、
単純変数または配列変数を "var" と表記します。
単純変数は単に
.RS
\fIname\fR
.RE
と表し、配列変数は
.RS
\fIname\fR[\fIexpr\fR]
.RE
と表します。特に言及しない限り、結果の有効桁数は、注目している式の
最大有効桁数になります。
.IP "- expr"
結果はその式の符号を反転したものとなります。
.IP "++ var"
変数を 1 だけインクリメントし、その新しい値が式の結果となります。
.IP "-- var"
変数を 1 だけデクリメントし、その新しい値が式の結果となります。
.IP "var ++"
式の結果はその変数の値となり、それからその変数を 1 だけ
インクリメントします。
.IP "var --"
式の結果はその変数の値となり、それからその変数を 1 だけ
デクリメントします。
.IP "expr + expr"
式の結果は 2 つの式の和となります。
.IP "expr - expr"
式の結果は 2 つの式の差となります。
.IP "expr * expr"
式の結果は 2 つの式の積となります。
.IP "expr / expr"
式の結果は 2 つの式の商となります。
結果の scale は変数 \fBscale\fR の値となります。
.IP "expr % expr"
結果は、以下のようにして求められる剰余です。a%b を求めるために、まず a/b を
\fBscale\fR の有効桁数で計算します。この結果を用いて、a-(a/b)*b を、
\fBscale\fR+scale(b) と scale(a) の大きい方の有効桁数で計算します。
もし \fBscale\fR に 0 がセットされ、両方の式が整数であれば、
整数の剰余が求められます。
.IP "expr ^ expr"
式の結果は、1 番目の式の値を 2 番目の回数だけ乗じたものになります。
2 番目の式は、整数でなければなりません。
(2 番目の式が整数でない場合は警告が表示され、
整数に切り詰めた値が使用されます。) 結果の scale は、べき指数が
負なら \fBscale\fR になります。べき指数が正なら、
"1 番目の式の scale とべき指数との積" および
"\fBscale\fR と 1 番目の式の scale の大きい方" のうちの小さい方
(つまり、scale(a^b) = min(scale(expr1)*expr2, max(scale, scale(expr1))))
となります。
expr^0 は常に 1 を返します。
.IP "( expr )"
標準の優先度を使わずに、この式の評価を優先します。
.IP "var = expr"
式の値が変数に代入されます。
.IP "var <op>= expr"
"var" が一度しか評価されないこと以外は "var = var <op> expr" と同じです。
"var" が配列の場合は動作が違うことがあり得ます。
.PP
関係演算は特殊な演算で、結果は常に 0 か 1 になります。関係が偽の時 0、
真の時 1 になります。関係演算は、演算式のどこでも使う事ができます。
(POSIX bcでは、関係演算は、if, while, for 文の中だけで、しかも
1 つの関係式しか使用できません。)
関係演算子は以下の通り。
.IP "expr1 < expr2"
expr1 が expr2 より小さい場合 1 になります。
.IP "expr1 <= expr2"
expr1 が expr2 より小さいか等しい場合 1 になります。
.IP "expr1 > expr2"
expr1 が expr2 より大きい場合 1 になります。
.IP "expr1 >= expr2"
expr1 が expr2 より大きいか等しい場合 1 になります。
.IP "expr1 == expr2"
expr1 と expr2 が等しい場合 1 になります。
.IP "expr1 != expr2"
expr1 と expr2 が等しくない場合 1 になります。
.PP
論理演算も使えます。(POSIX \fBbc\fR には論理演算はありません。)
論理演算も関係演算と同様、0 と 1 の 2 つの値 (各々偽および真)
だけをとる演算です。
論理演算子は以下の通り。
.IP "!expr"
expr が 0 なら 1 になります。
.IP "expr && expr"
expr1 と expr2 が両方とも 0 でないなら、1 になります。
.IP "expr || expr"
expr1 と expr2 のどちらか一方が 0 でないなら、1 になります。
.PP
各演算子の優先順位と結合規則は次の通りです。
(最初のものほど低く、後にいくほど高い優先順位で先に実行されます。)
.nf
.RS
|| operator, left associative
&& operator, left associative
! operator, nonassociative
Relational operators, left associative
Assignment operator, right associative
+ and - operators, left associative
*, / and % operators, left associative
^ operator, right associative
- (単項マイナス), nonassociative
++ and -- operators, nonassociative
.RE
.fi
.PP
この優先順位は、POSIX \fBbc\fR のプログラムがそのまま正しく動くように
配慮して決められています。このため、関係演算と論理演算を
代入文と共に用いた場合、通常とは異なる振る舞いをします。
次の例を考えてみましょう:
.RS
a = 3 < 5
.RE
.PP
C プログラマのほとんどは、
``3 < 5'' の関係演算が実行された結果が変数 ``a'' に代入される、
と考えるでしょう。
ところが \fBbc\fR では、まず 3 が変数 ``a'' に代入され、
それから 3 と 5 の比較が行われるのです。
この間違いを避けるために、
関係演算や論理演算を代入演算と共に用いる場合は、
括弧を使うのが最良です。
.PP
\fBbc\fR には特別な式がさらにいくつか備わっています。
それはユーザ定義関数と標準関数に関するもので、
すべて "\fIname\fB(\fIparameters\fB)\fR" という形をしています。
ユーザ定義関数については関数の章を参照して下さい。
標準関数は以下の通りです:
.IP "length ( expression )"
expression の有効桁数を返します。
.IP "read ( )"
(拡張機能) 関数の出現位置に関係なく、標準入力から数を読み取ります。
データとプログラムの両方を標準入力から与えるような場合には、
問題を生じうることに注意して下さい。
最良の方法は、
ユーザからデータの入力の必要があるなら、プログラムはあらかじめ作っておき、
標準入力からプログラムを入力しないようにすることです。
read 関数の値は標準入力から読み込んだ数です。
その際、変換基数として変数 \fBibase\fR の現在の値が用いられます。
.IP "scale ( expression )"
expression の小数点以下の有効桁数を返します。
.IP "sqrt ( expression )"
expression の平方根を返します。
expression に負の値を指定した場合は、ランタイムエラーになります。
.SS 文
文は (ほとんどの算術言語がそうであるように)、処理を順番に実行していく単位です。
\fBbc\fR では文は「できるだけ早い段階で」実行されます。
改行が入力された時点で、実行可能な文が存在していれば、即座に実行します。
このため \fBbc\fR では改行が重要な役割を持っています。
実際、セミコロンと改行が文の区切りとして使用されます。
不適当な場所で改行を入力すると、シンタックスエラーになります。
改行は文の区切りですが、バックスラッシュを用いて改行を隠すことができます。
\fBbc\fR にとって、"\e<nl>" (<nl>は改行) は改行ではなく空白に見えます。
文のリストは、セミコロンと改行で区切られた文の並びです。
以下、\fBbc\fR の文の種類とその動作について説明します。
(なお、以下の説明で ([]) で括った部分は省略可能な項です。)
.IP "演算式"
演算式には次の 2 つの種類があります。 
演算式が "<variable> <assignment> ..." で始まっていれば、
それは代入文として扱われます。
そうでなければ、演算式は評価されて出力に表示されます。
結果が表示された後、改行が表示されます。
例えば、"a=1" は代入文であり、
"(a=1)" は代入文が埋め込まれた演算式です。
表示される数値は全て、変数 \fBobase\fR で決まる基数で表示されます。
\fBobase\fR に指定できる値は 2 から BC_BASE_MAX までです。
(「制限」の章を参照。)
基数 2 から 16 まででは、通常の数表記法が用いられます。
基数が 16 より大きい場合、\fBbc\fR は、
各桁を 10 進表記する複数桁文字表記法で表示します。
複数桁文字表記法では、各桁は空白で区切られます。
各桁は "obase-1" を 10 進で表記するのに必要な桁数の数字から成ります。
数の精度は任意に選べるため、数によっては 1 行に表示できない場合もあります。
そのような長い数は、行末に "\e" を付けて次行に継続します。
1 行に表示できる文字数は 70 です。
\fBbc\fR の対話的性質により、ある数を表示すると、
表示した値が特殊変数 \fBlast\fR に代入されるという副作用が生じます。
ユーザはタイプし直すことなく最後に表示された値を再利用できます。
\fBlast\fR に値を代入することも可能で、
その場合、前回表示された値が代入値で上書きされます。
新しく代入した値は、次に数が表示されるか別の値が \fBlast\fR に代入される
まで有効です。(bc の実装によっては、
数の一部になっていない単一のピリオド (.) を \fBlast\fR の短縮表記として
用いることができます。)
.IP "string"
文字列 string が出力に表示されます。
文字列は二重引用符で始まり、次の二重引用符までの全ての文字を含みます。
改行を含め、全ての文字は文字通りに解釈されます。
文字列の後に改行は出力されません。
.IP "\fBprint\fR list"
print 文 (これは拡張機能です) は、もう一つの出力方法です。
"list" はコンマで区切った文字列および演算式のリストであり、
各文字列あるいは演算式がリストの順に表示されます。
最後に改行は出力されません。
演算式は評価され、その値が表示されるとともに、
変数 \fBlast\fR に代入されます。
print 文中の文字列は出力に表示されますが、特殊文字を含めることができます。
特殊文字はバックスラッシュ (\e) で始まります。
\fBbc\fR で使える特殊文字は、
"a" (ベル)、"b" (バックスペース)、
"f" (フォームフィード)、"n" (改行)、"r" (復帰)、"q" (二重引用符)、
"t" (タブ)、"\e" (バックスラッシュ) です。
これ以外は無視されます。
.IP "{ statement_list }"
複文です。複数の文を 1 つのグループにまとめて実行します。
.IP "\fBif\fR ( expression ) \fBthen\fR statement1 [\fBelse\fR statement2]"
if 文は演算式 expression を評価し、その値に応じて
文 statement1 または文 statement2 を実行します。
expression の値がゼロでなければ statement1 が実行されます。
statement2 が存在し、expression の値が 0 ならば、statement2 が実行されます。
(else 節は拡張機能です。)
.IP "\fBwhile\fR ( expression ) statement"
while 文は expression がゼロでない間、繰り返し statement を実行します。
statement の実行前に毎回 expression を評価します。
expression の値がゼロになるか、break 文を実行すると、
ループが終了します。
.IP "\fBfor\fR ( [expression1] ; [expression2] ; [expression3] ) statement"
for 文は statement の繰り返し実行を制御します。
expression1 はループ実行の前に評価されます。
expression2 は statement の実行前に毎回評価され、
その値がゼロでなければ statement が実行されます。
expression2 の値がゼロになると、ループは終了します。
各 statement 実行の後、再び expression2 が評価される前に expression3 が
評価されます。
expression1 あるいは expression3 が省略されていると、
そこでは何も評価されません。
expression2 が省略されている場合、expression2 が 1 であるのと
同様に扱われます。
(各 expression が省略可能なのは拡張機能です。
POSIX \fBbc\fR では、3 つの expression はどれも省略できません。)
 以下は for 文と等価なコードです:
.nf
.RS
expression1;
while (expression2) {
   statement;
   expression3;
}
.RE
.fi
.IP "\fBbreak\fR"
それを含む最も内側の while もしくは for 文による繰り返しを強制的に中断します。
.IP "\fBcontinue\fR"
それを含む最も内側の for 文による繰り返しで、最初の文に戻って実行を続けます。
(continue 文は拡張機能です)
.IP "\fBhalt\fR"
実行されると \fBbc\fR プロセッサを終了させます(拡張機能)。
例えば "if (0 == 1) halt" の場合は \fBbc\fR は終了しません。
halt 文が実行されないからです。
.IP "\fBreturn\fR"
関数から戻ります。関数の結果は 0 になります。(関数の章を参照)
.IP "\fBreturn\fR ( expression )"
関数から戻ります。関数の結果は expression になります。(関数の章を参照)
.SS 疑似文
これらは今までの文とは動作が異なります。
疑似文は実行文ではなく、「コンパイル」時点で処理されます。
.IP "\fBlimits\fR"
\fBbc\fR のローカルバージョンにより制限される限界値を表示します。
(limits は拡張機能です)
.IP "\fBquit\fR"
\fBbc\fR を終了します。どんな場所にあっても、quit 文は
入力された時点で実行されます。例えば、
"if  (0  ==  1)  quit"
という記述であっても、\fBbc\fR は終了します。
.IP "\fBwarranty\fR"
保証に関する注意を長めに表示します。
(warranty は拡張機能です)
.SS 関数
関数は、後で実行されるべき計算手順を定義する機能です。
.B bc
の関数は常に値を計算し、それを呼びだし側に返します。
関数定義は、それが入力から読み込まれた時点で定義が行われるという点で
「ダイナミック(動的)」です。
一度定義された関数は、同じ名前で別の関数が定義されるまで使用可能で、
新しい関数が定義された場合は、前の関数が置き換えられます。
関数の定義は、以下のように行います:
.nf
.RS
\fBdefine \fIname \fB( \fIparameters \fB) { \fInewline
\fI    auto_list   statement_list \fB}\fR
.RE
.fi
関数呼び出しは、
"\fIname\fB(\fIparameters\fB)\fR"
という形式の演算式です。
.PP
パラメータ parameters は数あるいは配列 (拡張機能) です。
関数定義では、ゼロあるいは 1 個以上のパラメータ名を
コンマで区切って並べることで定義します。
数は値渡し(call by value)でのみ渡され、配列は変数渡し(call by variable)で
のみ渡されます。
配列はパラメータ定義中で "\fIname\fB[]\fR" のように表記して指定します。
関数呼び出しでは、数のパラメータに対して完全な演算式の実パラメータを
記述します。
配列を渡す表記は配列パラメータ定義と同様です。
名前付き配列は変数(variable)によって関数に渡されます。
関数定義はダイナミックゆえ、
パラメータの数と型は関数呼び出しの際にチェックされます。
パラメータの数あるいは型に何らかの不整合があると、
ランタイムエラーが発生します。
未定義関数を呼び出した場合もランタイムエラーとなります。
.PP
\fIauto_list\fR は省略可能で、ローカル変数として使用する変数のリスト
です。auto_list が存在するなら、その文法は
"\fBauto \fIname\fR, ... ;"
となります。(セミコロンはオプションです。)
各 \fIname\fR がローカル変数の名前となります。
配列はパラメータと同様の表記で指定できます。
これらの変数は、関数の最初でその値がスタックにプッシュされたのち
値ゼロに初期化され、関数の実行中に使用されます。
これらの変数は関数出口にてポップされ、
(関数呼び出し時の)元の値が復元されます。
パラメータは実際にはローカル変数であり、
関数呼び出しで与えられた値に初期化されます。
bc のローカル変数は伝統的な意味でのローカル変数と異なり、
関数 A が関数 B を呼び出しているような場合、関数 B の中に
関数 A のローカル変数と同じ名前のローカル変数がない限り、
関数 A のローカル変数名をそのまま使って、
関数 B から関数 A のローカル変数をアクセスできます。
ローカル変数とパラメータはスタックにプッシュされるため、
\fBbc\fR は再帰的な関数呼び出しをサポートしています。
.PP
関数本体は \fBbc\fR の文のリストです。
繰り返し述べますと、文はセミコロンか改行で区切られています。
return 文により関数は終了し、値を返します。
return 文には 2 つの形式があり、
ひとつめの形式 "\fBreturn\fR" は、呼び出し元に値 0 を返します。
もうひとつの形式 "\fBreturn ( \fIexpression \fB)\fR" は、
expression の値を計算し、それを呼び出し元に返します。
各関数の最後には "\fBreturn (0)\fR" があるものと解釈されます。
これにより、明示的に return 文を置かなくても、
関数は終了して値 0 を返します。
.PP
関数の中では、変数 \fBibase\fR の動作が変わります。関数の中で使われて
いる定数は、関数の呼びだし時点の \fBibase\fR を元に変換が行われます。
このため、関数内部で \fBibase\fR を変更しても無視されます。ただし、標
準関数 \fBread\fR を呼び出した場合は例外で、これは常に現在の
\fBibase\fR の値をもとに変換が行われます。
.SS 数学ライブラリ
\fBbc\fR に \fB-l\fR オプションを付けて起動した場合は、数学ライブラリが
読み込まれ、デフォルトの scale が 20 に設定されます。
数学関数は、それを呼び出した時点の scale の値に従って計算を行います。
数学ライブラリによって使用可能になる関数は、次の通りです:
.IP "s (\fIx\fR)"
sin (x の単位はラジアン)
.IP "c (\fIx\fR)"
cos
.IP "a (\fIx\fR)"
atan
.IP "l (\fIx\fR)"
log (自然対数)
.IP "e (\fIx\fR)"
exp
.IP "j (\fIn,x\fR)"
ベッセル関数
.SS 使用例
次の例は、/bin/sh でシェル変数 \fBpi\fR に ``パイ'' の値を代入します。
.RS
\f(CW
pi=$(echo "scale=10; 4*a(1)" | bc -l)
\fR
.RE
.PP
次の例は、数学ライブラリで使われている ``e (x)'' の定義です
この関数は POSIX \fBbc\fR で記述されています。
.nf
.RS
\f(CW
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
  }
}
\fR
.RE
.fi
.PP
次の例は、\fBbc\fR の拡張機能を使って、``checkbook balances'' 
(小切手帳残高) を計算する簡単なプログラムです。
このプログラムをファイルにしておくと、
毎回タイプしなおさずに何度も使うことができます。
.nf
.RS
\f(CW
scale=2
print "\enCheck book program!\en"
print "  Remember, deposits are negative transactions.\en"
print "  Exit by a 0 transaction.\en\en"

print "Initial balance? "; bal = read()
bal /= 1
print "\en"
while (1) {
  "current balance = "; bal
  "transaction? "; trans = read()
  if (trans == 0) break;
  bal -= trans
  bal /= 1
}
quit
\fR
.RE
.fi
.PP
次の例は、再帰呼び出しにより階乗を計算する関数です。
.nf
.RS
\f(CW
define f (x) {
  if (x <= 1) return (1);
  return (f(x-1) * x);
}
\fR
.RE
.fi
.SS 相違点
このバージョンの
.B bc
は POSIX P1003.2/D11 ドラフトから実装されており、
そのドラフトや以前の実装に比べていくつかの相違点や拡張点があります。
伝統的に行われていたような
.I dc(1)
を用いた実装ではありません。
このバージョンは単一プロセスであり、
プログラムをバイトコードに変換したものを解析して実行します。
「ドキュメントに記載されていない」オプション (-c) があり、
プログラムを実行する代わりに、それをバイトコードに変換した結果を
標準出力に出力します。
これは主として、パーザのデバッグと数学ライブラリの準備に用いられました。
.PP
主な相違点は拡張機能によるものです。
機能を高めたり追加したりするために機能が拡張されたり、
新機能が追加されたりしています。
相違点と拡張点のリストを以下に示します。
.IP LANG
このバージョンは、
環境変数 LANG および LC_ で始まる全ての環境変数の処理に関して POSIX に
準拠していません。
.IP 名前
伝統的な
.B bc
および POSIX
.B bc
は、関数、変数、配列の名前として単一の文字を使います。
このバージョンでは、
先頭が文字で始まり、文字と数字とアンダースコアから成る文字で
構成される 2 文字以上の名前が使えるように拡張されています。
.IP 文字列
文字列には NUL 文字を含むことはできません。
POSIX では、文字列にはあらゆる文字を含めることができなければならない、
としています。
.IP last
POSIX \fBbc\fR には変数 \fBlast\fR はありません。
\fBbc\fR の実装によっては、\fBlast\fR と同じ意味で
ピリオド (.) を用いるものがあります。
.IP 比較
POSIX \fBbc\fR では、比較は if 文、while 文、for 文の第 2 式の中でのみ
用いることができます。
また、これらの文の中ではただ一つの関係演算しか使えません。
.IP "if 文, else 節"
POSIX \fBbc\fR には else 節はありません。
.IP "for 文"
POSIX \fBbc\fR では for 文の各演算式は省略できません。
.IP "&&, ||, !"
POSIX \fBbc\fR には論理演算子はありません。
.IP "read 関数"
POSIX \fBbc\fR には read 関数はありません。
.IP "print 文"
POSIX \fBbc\fR には print 文はありません。
.IP "continue 文"
POSIX \fBbc\fR には continue 文はありません。
.IP "配列パラメータ"
POSIX \fBbc\fR では配列パラメータは使えません。
他の \fBbc\fR の実装では、値渡しで配列パラメータを使えるものがあります。
.IP "=+, =-, =*, =/, =%, =^"
POSIX \fBbc\fR ではこれらの「旧式」の代入演算子を定義する必要はありません。
このバージョンではこれらの「旧式」代入演算子が使えるかも知れません。
limits 文を使って、インストールしたバージョンがこれらをサポートしているか
どうか、確かめてみて下さい。
もしそのバージョンが「旧式」代入演算子をサポートしていれば、
文 "a =- 1" は \fBa\fR に値 -1 を代入する代わりに \fBa\fR を 1 減じます。
.IP "数字表記中の空白"
他の \fBbc\fR 実装では、数字表記の中に空白を含めることが許されます。
例えば、"x=1 3" は変数 x に値 13 を代入します。
このバージョンの \fBbc\fR では、先の文は文法エラーになります。
.IP "エラーと実行"
このバージョンの bc は、
プログラムに文法上のエラーや他のエラーが見つかった場合に
どういうコードが実行されるか、
という点で、他の実装と異なっています。
ある関数定義中で文法エラーが見つかると、
エラー回復機構は文の先頭を見つけて関数のパーズを続けようと努力します。
ひとたび関数の中で文法エラーが見つかると、
その関数は呼び出せなくなり、未定義状態となります。
対話的実行コードで文法エラーがあると、
現在の実行ブロックが無効になります。
実行ブロックとは、ひと続きの完全な文のあとの行末までのことです。
例えば、次のコード
.nf
.RS
a = 1
b = 2
.RE
.fi
には 2 つの実行ブロックがあり、
.\" ↑ここで groff 時の字下げ量がおかしくなっているようだが、
.\" 元の英語マニュアルでもそうなっているようだ。(jpman 酒井)
.nf
.RS
{ a = 1
  b = 2 }
.RE
.fi
には 1 つの実行ブロックがあります。
ランタイムエラーが発生すると、現在の実行ブロックの実行が終了します。
ランタイムの警告が発生しても、現在の実行ブロックは終了しません。
.IP "割り込み"
対話セッションの間、SIGINT シグナル (通常、端末からの Control-C 入力で
発生します) によって現在の実行ブロックの実行が中断され、
どの関数が中断されたかを示す「ランタイム」エラーが表示されます。
ランタイムのデータ構造を全てクリアした後メッセージが表示され、
\fBbc\fR は次の入力を受け付ける状態になったことを示します。
これまでに定義した関数は全て定義されて残っており、
ローカルでない変数の値は割り込み発生時点の値のままになっています。
ローカル変数と関数パラメータは全て、クリア処理によって消去されます。
非対話セッションでは、SIGINT シグナルで \fBbc\fR の実行全体が終了します。
.SS 限界
以下の項目が現在の
.B bc
プロセッサの限界値となっています。
このうちいくつかは、インストール時に変更できます。
実際の値を得るには limits 文を使って下さい。
.IP BC_BASE_MAX
現在のところ、出力の基数の最大値は 999 に設定されています。
入力側の基数の最大値は 16 です。
.IP BC_DIM_MAX
現在のところ 65535 として配布されていますが、
インストールしたバージョンでは異なっているかも知れません。
.IP BC_SCALE_MAX
小数点以下の桁数は INT_MAX 桁に制限されています。
また、小数点より上の桁数も INT_MAX 桁に制限されています。
.IP BC_STRING_MAX
文字列中の文字数は INT_MAX 文字に制限されています。
.IP 指数
累乗演算 (^) の指数の値は LONG_MAX に制限されています。
.IP 乗算
全部で LONG_MAX / 90 桁以上になる数の積を計算すると
誤った結果になることがあります。
32 ビット long では、この数は 23,860,929 桁です。
.IP コードサイズ
各関数および "main" プログラムはバイトコードで 16384 バイト以内に
制限されています。
この限界値 (BC_MAX_SEGS) は 1024 バイトの 16 セグメント以上になるように
容易に変更可能です。
.IP 変数名
単純変数、配列、関数各々について、一意に識別される名前は 32767 個に
制限されています。
.SH 関連ファイル
ほとんどの実装では、\fBbc\fR は完全に自分自身で独立しています。
実行ファイルのサイズが重要視される場合や、
C コンパイラが長い文字列を扱えない場合は、
\fBbc\fR は /usr/local/lib/libmath.b から標準の数学ライブラリを読み込みます。
(実際のディレクトリ位置はこれとは異なり、
例えば /lib/libmath.b かも知れません。)
.SH 診断
コマンドラインで指定したファイルがオープンできない場合、
\fBbc\fR はファイルが利用できない旨を表示して終了します。
また、コンパイル時あるいはランタイムの診断メッセージもありますが、
それらは自身で理解できるようになっているはずです。
.SH バグ
エラーリカバリがまだうまくいっていません。
.SH 作者
.nf
Philip A. Nelson
phil@cs.wwu.edu
.fi
.SH 謝辞
実装をテストする際に
広範囲に手助けしてくれた Steve Sommars (Steve.Sommars@att.com) に感謝します。
たくさんの素晴らしい意見をもらいました。
彼のおかげでとてもよいものになりました。