aboutsummaryrefslogblamecommitdiff
path: root/ja_JP.eucJP/man/man3/math.3
blob: 08e7949fd427402bd721d30182e0e658ae5fc6a0 (plain) (tree)
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































                                                                              
                                                          
   
             


































































































































































































































































































































































































































































































































                                                                                
                                                                      
                                                        
                                                                






















                                                                      
.\" Copyright (c) 1985 Regents of the University of California.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\"    notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\"    notice, this list of conditions and the following disclaimer in the
.\"    documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\"    must display the following acknowledgement:
.\"	This product includes software developed by the University of
.\"	California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\"    may be used to endorse or promote products derived from this software
.\"    without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\"	from: @(#)math.3	6.10 (Berkeley) 5/6/91
.\"	%Id: math.3,v 1.7 1998/02/04 22:30:18 jlemon Exp %
.\"
.\" $FreeBSD$
.TH MATH 3M "May 6, 1991"
.UC 4
.ds up \fIulp\fR
.ds nn \fINaN\fR
.de If
.if n \\
\\$1Infinity\\$2
.if t \\
\\$1\\(if\\$2
..
.SH 名称
math \- 数学ライブラリ関数の導入
.SH 解説
この関数は、C の数学ライブラリ
.I libm
を構成します。リンクエディタは、\*(lq\-lm\*(rq
オプションが指定されると、このライブラリを検索します。この関数の
宣言は、インクルードファイル
.Ri < math.h >
で入手できます。
.SH 関数リスト
以下のそれぞれの倍精度浮動小数点数関数は、単精度関数と対になっており、
名前が f で終わる関数は単制度浮動小数点数を扱います。たとえば
acos(double x)
は、浮動小数を扱う
acosf(float x)
と対になっています。
.sp
.nf
.ta \w'copysign'u+2n +\w'infnan.3m'u+10n +\w'inverse trigonometric func'u
\fI名称\fP	\fIページ\fP	\fI解説\fP	\fIエラー拘束 (ULP)\fP
.ta \w'copysign'u+4n +\w'infnan.3m'u+4n +\w'inverse trigonometric function'u+6nC
.sp 5p
acos	sin.3m	逆三角関数	3
acosh	asinh.3m	逆双曲線関数	3
asin	sin.3m	逆三角関数	3
asinh	asinh.3m	逆双曲線関数	3
atan	sin.3m	逆三角関数	1
atanh	asinh.3m	逆双曲線関数	3
atan2	sin.3m	逆三角関数	2
cabs	hypot.3m	複素絶対値	1
cbrt	sqrt.3m	立方根	1
ceil	floor.3m	以上の整数	0
copysign	ieee.3m	符号ビットのコピー	0
cos	sin.3m	三角関数	1
cosh	sinh.3m	双曲線関数	3
erf	erf.3m	誤差関数	???
erfc	erf.3m	補足誤差関数	???
exp	exp.3m	指数	1
expm1	exp.3m	exp(x)\-1	1
fabs	floor.3m	絶対値	0
floor	floor.3m	以下の整数	0
hypot	hypot.3m	ユークリッド距離	1
ilogb	ieee.3m	指数抽出	0
j0	j0.3m	ベッセル関数	???
j1	j0.3m	ベッセル関数	???
jn	j0.3m	ベッセル関数	???
lgamma	lgamma.3m	対数ガンマ関数(旧 gamma.3m)
log	exp.3m	自然対数	1
log10	exp.3m	底が10の対数	3
log1p	exp.3m	log(1+x)	1
pow	exp.3m	指数 x**y	60\-500
remainder	ieee.3m	余り	0
rint	floor.3m	最も近い整数に丸める	0
scalbn	ieee.3m	指数調整	0
sin	sin.3m	三角関数	1
sinh	sinh.3m	双曲線関数	3
sqrt	sqrt.3m	平方根	1
tan	sin.3m	三角関数	3
tanh	sinh.3m	双曲線関数	3
y0	j0.3m	ベッセル関数	???
y1	j0.3m	ベッセル関数	???
yn	j0.3m	ベッセル関数	???
.ta
.fi
.SH 注釈
カリフォルニア大学から 1985 年末に配布された 4.3 BSD では、上記の関数に
2 つのバージョンが用意されています。1 つは DEC VAX\-11 ファミリの
コンピュータの倍精度 "D" フォーマットで、もう 1 つは IEEE 754 標準の
バイナリ浮動小数点数演算に準拠した倍精度演算です。
UNIX が誕生したときのものよりも、他のプログラムが正確で頑丈になったこと
から予想できるように、この 2 つのバージョンも、非常に似たような
挙動を示します。たとえば、これらのプログラムは、上の表の \*(ups の
数以内で正確です。\*(up は、最終桁の単位です。これらのプログラムは、
かつての数学ライブラリ \fIlibm\fR で発生していた異常状態を修正しました。
この異常状態が発生すると、以下のような結果が得られていました。
.RS
sqrt(\-1.0) = 0.0 であり log(\-1.0)= \-1.7e38
.br
cos(1.0e\-11) > cos(0.0) > 1.0
.br
x = 2.0, 3.0, 4.0, ..., 9.0 のときに、pow(x,1.0)
.if n \
!=
.if t \
\(!=
x
.br
pow(\-1.0,1.0e10) が整数オーバフロー例外を起こしていた
sqrt(1.0e30) と sqrt(1.0e\-30) の計算が非常に遅かった
.RE
しかしこの 2 つのバージョンには、説明しなければならない
違いがあります。以下に注意してください。
.PP
\fBDEC VAX\-11 D_floating\-point:\fR
.PP
これは、オリジナルの数学ライブラリ \fIlibm\fR が開発されたフォーマット
であり、このマニュアルが原則的に依って立つフォーマットです。これは、
PDP\-11 および初期の VAX\-11 マシンの倍精度フォーマットです。
1983 年以降の VAX\-11 は、IEEE 倍精度フォーマットにより近い、
オプションの "G" フォーマットを備えています。初期の
DEC MiroVAX には D フォーマットがなく、G 倍精度のみが
備わっています。
.PP
D_floating\-point のプロパティ:
.RS
ワードサイズ: 64 ビット、8 バイト。基数: バイナリ。
.br
精度: 56 ビット、10 進数で約 17 桁。
.RS
x と x' が連続した正の D_floating\-point 浮動小数点数
(1 \*(up ずつ異なる) である場合は、
.br
1.3e\-17 < 0.5**56 < (x'\-x)/x \(<= 0.5**55 < 2.8e\-17
.br
となる。
.RE
.nf
.ta \w'Range:'u+1n +\w'Underflow threshold'u+1n +\w'= 2.0**127'u+1n
範囲:	オーバフローしきい値	= 2.0**127	= 1.7e38
	アンダーフローしきい値	= 0.5**128	= 2.9e-39
	注意: この範囲は相対的に狭くなっています。
.ta
.fi
.RS
オーバフローが発生すると、計算は常に中断されます。
.br
アンダーフローが発生すると、ゼロになります。
.br
警告:
.RS
アンダーフローにより、x
.if n \
!=
.if t \
\(!=
y で x\-y = 0 となる可能性があります。同じように、
x  > y > 0 であっても、x\(**y = 0 もしくは
y/x = 0 ということが警告なしに発生してしまいます。
.RE
.RE
ゼロは曖昧に表現されます。
.RS
ハードウェアでは、2**55 通りのゼロの表現を受理しますが、
生成されるものは明らかな表現だけです。
VAX には -0 がありません。
.RE
VAX アーキテクチャには無限 (
.If
) もありません。
.br
予約オペランド:
.RS
ハードウェアは 2**55 通りを認識しますが、生成されるものは 1 つだけです。
予約オペランドに対する浮動小数演算は、MOVF や MOVD でさえ計算を中断する
ので、あまり使用されません。
.RE
例外:
.RS
ゼロ除算とオーバフローするオペレーションは不正なオペレーションで、
計算は中断されます。古いマシンでは予約オペランドが作成され、
計算が中断されます。
.RE
丸め:
.RS
 (PDP\-11 では必ずしもそうとは言えませんが) VAXでのすべての有理数演算
(+, \-, \(**, /) は、オーバフロー、アンダーフロー、ゼロ除算が
発生しない場合、\*(up の半分以内に丸められます。丸め誤差が \*(up
のちょうど半分である場合、丸めは 0 から離れます。
.RE
.RE
.PP
範囲が狭いことを別にすると、D_floating\-point は、1960 年代に設計された
ものとしては優れたコンピュータ算術演算のひとつです。
D_floating\-point のプロパティは、4.3 BSD で配布された VAX の
基本的な関数に忠実に反映されています。オーバフローや
アンダーフローが発生するのは、結果が範囲外になるか範囲外に非常に近い
場合のみで、その場合はオーバフローやアンダーフローを起こす有理算術
オペレーションと同じような動作をします。同じように、log(0) と atanh(1)
のような式は 1/0 のように動作し、sqrt(\-3) と acos(3) は 0/0
のように動作します。これらはすべて予約オペランドを作成し、
計算は中断されます。この状況については、
それぞれのマニュアルページで詳しく説明します。
.RS
.ll -0.5i
このレスポンスは厳し過ぎるので、すべての浮動小数演算の例外を適切に
処理するように開発された、柔軟で統一されたスキームで近い将来に
置き換えられる予定です。
.\" See infnan(3M) for the present state of affairs.\fR
.ll +0.5i
.RE
.PP
UNIX 用 4.3 BSD の新しい \fIlibm\fR の関数を DEC の VAX/VMS ライブラリと
比較すると、一部の VMS 関数は多少速く、一部は多少精度が高く、一部は
かなり例外に厳しくなって(pow(0.0,0.0) と atan2(0.0,0.0) など)おり、
ほとんどは、\fIlibm\fR よりも多くのメモリを使用します。
VMS コードは、大きいテーブルで補間して速さと精度を達成しています。
\fIlibm\fR コードは、将来はすべてが ROM に収まりそうなほど
小型で相当工夫を凝らした式を使用しています。
.PP
それより重要なことは、DEC が VMS コードを特許とみなし、許可なく
使用することを厳しく禁じているのに対し、4.3 BSD の \fIlibm\fR コードは
public domain を意図しているということです。つまり、
出所を常に明らかにして、ユーザがコードを使用した感想を報告して
コードの作者の研究に協力する限りにおいて、\fIlibm\fR コードは自
由にコピーできます。それゆえ、算術処理が VAX D_floating\-point
に似ているマシンの UNIX ユーザであっても、新しい \fIlibm\fR よりも
劣るものを使用する必要がないということです。
.PP
\fBIEEE STANDARD 754 浮動小数点数算術演算:\fR
.PP
この標準は、他のコンピュータ算術演算方式よりも広く
採用されてきています。以下のような多くのメーカが、この標準の一部の
バージョンに準拠した VLSI チップを製造しています。
.nf
.ta 0.5i +\w'Intel i8070, i80287'u+6n
	Intel i8087, i80287	National Semiconductor  32081
	Motorola 68881	Weitek WTL-1032, ... , -1165
	Zilog Z8070	Western Electric (AT&T) WE32106.
.ta
.fi
この他にも、ソフトウェアによる実装 (Apple Macintosh は完璧にそれ) から、
Hewlett-Packard 9000 シリーズの VLSI による実装や、果ては ECL を
駆使し、3 Megaflop を達成した ELXSI 6400 まで極めて広い実装の幅を
誇ります。他の企業の中には、丸め、オーバフロー、アンダーフロー
などの例外の処理でこの標準の方法に従わずに、IEEE 754 のフォーマット
だけを採用しています。
DEC VAX G_floating\-point フォーマットは、IEEE 754 Double 
フォーマットに非常に似ているので、上に挙げたほとんどの初等関数の
IEEE バージョンの C プログラムは、MicroVAX で実行するように簡単に
変換できますが、わざわざ変換してやろうという人はいないようです。
.PP
4.3 BSD \fIlibm\fR のコードのうち、IEEE 754 準拠マシン用のものは、 
National Semi. 32081 と WTL 1164/65 用になっています。
Intel チップや Zilog チップ、または Apple Macintosh か ELXSI 6400
でこのコードを使用する場合は、これらの企業が提供するよりよいコード
(無料になると思われる) か、上のコードの作者が設計した
コードを使用することになります。
\fIatan\fR, \fIcabs\fR, \fIcbrt\fR, \fIerf\fR, \fIerfc\fR, \fIhypot\fR,
\fIj0\-jn\fR, \fIlgamma\fR, \fIpow\fR, \fIy0\-yn\fR を除けば、
Motorola 68881 は \fIlibm\fR のすべての関数をチップに搭載し、
しかもより速く正確になっています。
Motorola, Apple, i8087, z8070, WE32106 では、
有効桁数 64 ビットを使用しています。4.3 BSD の \fIlibm\fR コードには、
public domain を意図しているという長所があります。
出所を常に明らかにし、ユーザがコードを使用した感想を報告して
作者の研究に協力すれば、\fIlibm\fR コードは自由にコピーできます。
算術演算が IEEE 754 に似ているマシンの UNIX ユーザは、新しい \fIlibm\fR
に劣るものを使用する必要がないということです。
.PP
IEEE 754 Double-Precision のプロパティ:
.RS
ワードサイズ: 64 ビット、8 バイト、基数: バイナリ
.br
精度: 53 ビット、(10 進数で) 約 16 桁。
.RS
x と x' が連続した正の倍精度浮動小数点数である
(1 \*(up ずつ異なる) 場合は、
.br
1.1e\-16 < 0.5**53 < (x'\-x)/x  \(<=  0.5**52  < 2.3e\-16
となる。
.RE
.nf
.ta \w'範囲:'u+1n +\w'アンダーフロー閾値'u+1n +\w'= 2.0**1024'u+1n
範囲:	オーバフローしきい値	= 2.0**1024	= 1.8e308
	アンダーフローしきい値	= 0.5**1022	= 2.2e-308
.ta
.fi
.RS
オーバフローが発生すると、デフォルトで符号付きの無限になります。
アンダーフローは 0.5**1074 = 4.9e-324 の倍数の整数のうち最も
近いものに段階的に丸められます。
.RE
ゼロは、+0 か \-0 のようにあいまいに表現されます。
.RS
符号は乗算か除算で正しく変換され、符号付きゼロの加算で維持されます。
しかし x が有限の 場合、x\-x は +0 になります。0 の符号が
問題になる演算は、0 除算と copysign(x,\(+-0) のみです。
とくに比較 (x > y, x \(>= y など) はゼロの符号から
影響を受けませんが、有限な値 x = y である場合は、
.If
\&= 1/(x\-y)
.if n \
!=
.if t \
\(!=
\-1/(y\-x) =
.If \-
になります。
.RE
.If
は符号付きです。
.RS
.If
をそれ自身か有限の数値に加算しても
無限は維持されます。
.If
の符号は乗算と除算で正しく変換され、
.If (有限値)/\(+- \0=\0\(+-0
(非ゼロ値))/0  =
.If \(+-
になります。しかし、
.if n \
無限\-無限, 無限\(**0, 無限/無限
.if t \
\(if\-\(if, \(if\(**0, \(if/\(if
は、0/0 や sqrt(\-3) と同様に不正な演算であり、\*(nn が生成されます。
.RE
予約オペランド:
.RS
2**53\-2 通りの予約オペランドがあり、すべて
\*(nn (\fIN\fRot \fIa N\fRumber) と呼ばれます。一部は発信 \*(nn
と呼ばれ、それに対して浮動小数点演算を実行するとトラップが発生します。
値の欠落か未初期化、または配列の存在しない要素をマークするために
使用されます。その他は無発信 \*(nn と呼ばれます。これは
不正演算の結果のデフォルト値で、それ以後の算術演算に影響が波及します。
x
.if n \
!=
.if t \
\(!=
x である場合、x は \*(nn です。その他すべての論理演算
(x > y, x = y, x < y など) は、\*(nn が関係する場合は
偽になります。
.br
注意: \*(nn は三分法を妨害します。
.RS
\*(nn が関係する場合、純粋な (不) 等値演算ではなく
順序付け比較を伴う論理演算は
偽になるだけでなく、不正演算となります。
.RE
.RE
丸め:
.RS
デフォルトでは、すべての代数演算 (+, \-, \(**, /,
.if n \
sqrt)
.if t \
\(sr)
は、\*(up の半分以内に丸められます。丸め誤差が \*(up 
のちょうど半分である場合、丸めた値の最下位有効ビットはゼロになります。
通常はこのような丸めが最適で、たとえば
x = 1.0, 2.0, 3.0, 4.0, ..., 2.0**52
である場合、商と積の両方が丸められるにも関わらず、
(x/3.0)\(**3.0 == x, (x/10.0)\(**10.0 == x, ...
になります。このような結果となるのは、IEEE 754 のような丸めのみです。
しかし 1 つの丸めがどの状況でも最適であるとは限らないため、
IEEE 754 では、ゼロへの丸め、
.If +
への丸め、
.If -
への丸めをプログラマが選択できるようになっています。最低でも
1.0e\-10 から 1.0e37 くらいまででは、
バイナリと小数の変換に同じ種類の丸めを指定できます。
.RE
例外:
.RS
IEEE 754 では、5 種類の浮動小数例外が認識されます。
以下では、重要な順にその 5 種類を挙げます。
.RS
.nf
.ta \w'Invalid Operation'u+6n +\w'Gradual Underflow'u+2n
例外	デフォルトの結果
.tc \(ru

.tc
不正演算	\*(nn, または偽
.if n \{\
オーバフロー	\(+-無限
ゼロ除算	\(+-無限 \}
.if t \{\
オーバフロー	\(+-\(if
ゼロ除算	\(+-\(if \}
アンダーフロー	段階的アンダーフロー
不精密	丸めた値
.ta
.fi
.RE
注意:  例外は、適切に処理されればエラーではありません。
例外を例外的なものにしてしまうのは、すべての例を満たす
デフォルトレスポンスがない場合です。逆に、デフォルトレスポンスが
ほとんどの例を満たす場合、それでも満たされない例を、
例外が発生するたびに演算を中断するという手で正当化することは
できません。
.RE
.PP
IEEE 754 では、それぞれの浮動小数例外のためにフラグを
用意しています。このフラグは例外が発生するたびに上がり、プログラムで
リセットするまで、上がった状態で残ります。プログラムでは、フラグのテスト、
保存、復元もできます。
IEEE 754 には、デフォルトの結果が満足の行くものでない
例外にプログラムで対処する方法として、以下の 3 つがあります。
.IP 1) \w'\0\0\0\0'u
後で例外の原因となる可能性がある条件をテストし、その
テスト結果に従って処理を変えて例外を避ける。
.IP 2) \w'\0\0\0\0'u
フラグをテストし、プログラムで最後にフラグをリセット
してから例外が発生したかどうかを確認する。
.IP 3) \w'\0\0\0\0'u
結果をテストし、1 つの例外のみが発生する値であるかどうかを確認する。
.RS
警告: アンダーフローが発生したかどうかを確実に発見するには、
積や商がアンダーフローしきい値よりゼロに近いかどうかをテスト
するか、アンダーフローフラグをテストするしかありません。
(IEEE 754 では、和と差がアンダーフローを起こすことはありません。
x
.if n \
!=
.if t \
\(!=
y である場合、x\-y は完全に正確で、値が小さくてもゼロではありません。
) 段階的にアンダーフローを起こす積と商は、徐々に精度を失っても
ゼロにはならないため、ゼロと比較しても (VAX で実行する可能性がある)、
ロスは明らかになりません。段階的にアンダーフローを起こした値を
アンダーフローしきい値より大きい値と加算する場合、段階的な
アンダーフローで失われる桁は切り捨てられるので失われません。
このため、通常の場合、段階的なアンダーフローは無視できることがあります。
ゼロにフラッシュされるアンダーフローでは、同じことが正しいとは限りません。
.RE
.PP
IEEE 754 に準拠するシステムでは、以下のような方法でも例外に
対処できます。
.IP 4) \w'\0\0\0\0'u
異常終了 (ABORT)。このメカニズムでは、「ON ERROR GO TO」のような
エラー処理ステートメントに関連する方法で処理する事がらとして、例外を
前もって分類します。言語が異なれば、このステートメントの形式は
変わりますが、次のような共通した特徴があります。
.IP \(em \w'\0\0\0\0'u
例外を起こした演算結果の値を代用し、式の途中から計算を
再開する方法がなくなります。例外の結果は放棄されます。
.IP \(em \w'\0\0\0\0'u
エラー処理ステートメントがないサブプログラムでは、どの
プログラムが呼び出してもそのサブプログラムは例外のために異常終了し、
エラー処理ステートメントが見つかるまでサブプログラムが次々に呼び
出されるか、タスク全体が異常終了してメモリのダンプが取られます。
.IP 5) \w'\0\0\0\0'u
停止(STOP)。対話型のデバッグ環境が必要になるこのメカニズムは、
プログラマ用であってプログラム向きではありません。例外はプログラマの
間違いの兆候として前もって分類されます。例外が発生すると、例外を起こした
オペレーションの近くで実行が停止されるので、プログラマは、例外がどのように
発生したのかを確認できます。多くの場合は、最初の数個の例外は大きな
問題ではなく、プログラマはそれぞれの例外が発生するたびに、実行が
停止されなかったかのように実行を再開できます。
.IP 6) \w'\0\0\0\0'u
\&... その他の方法については、この文書では説明しません。
.RE
.PP
例外処理には、範囲 (scope) という重大な問題があります。問題の解決策は
分かっていますが、人手不足のため、4.3 BSD の \fIlibm\fR で配布するとき
までに完全に実現できませんでした。理想的には、それぞれの初等関数を、
次のような意味で分割せずに自動的に動作させる必要があります。
.IP i) \w'iii)'u+2n
関数に提供したデータが値しない例外を発生させない。
.IP ii) \w'iii)'u+2n
発生したすべての例外をその関数で識別し、サブルーチンでは
識別しない。
.IP iii) \w'iii)'u+2n
関数の定義が例外処理と関連しているにも関わらず、上記 5 つの
例外処理方法によって呼出し側プログラムを変更し、小さな関数の
内部処理を中断しない。
.PP
プログラマが、デバッグ済みサブプログラムをユーザが気付かないような
小さなものに簡単にできるようになれば理想的です。しかし、小さな関数の
3 つすべての特徴をシミュレートすることは、多くのテスト、保存、復元が
伴うため、厄介な作業になっています。現在、この不便さを改善する作業が
進んでいます。
.PP
この作業が進むまで、\fIlibm\fR の関数はそれほど小さくなりませんが、
以下の場合を除き、不適切な例外を発生させません。
.RS
オーバフロー/アンダーフロー
.RS
正しく計算した結果が、範囲内に収まっている場合。
.RE
\fIcabs\fR, \fIcbrt\fR, \fIhypot\fR, \fIlog10\fR, \fIpow\fR
の不正。
.RS
エラーの偶発的な取り消しによって正確になった場合。
.RE
.RE
その他の場合
.RS
不正演算は、以下のような場合にのみ発生します。
.RS
\*(nn 以外の結果が誤っていると思われる場合。
.RE
オーバフローは、以下のような場合にのみ発生します。
.RS
正しい結果が有限であるが、オーバフローしきい値を
越えている場合。
.RE
ゼロ除算は、以下のような場合にのみ発生します。
.RS
有限演算で、関数が無限の値を受けた場合。
.RE
アンダーフローは、以下のような場合にのみ発生します。
.RS
正しい結果がゼロではないが、アンダーフローしきい値より
小さい場合。
.RE
不正確は、以下のような場合にのみ発生します。
.RS
正しい結果の表現に、より広い範囲かより高い精度が必要な
場合。
.SH バグ
シグナルが適切である場合、そのシグナルはコードの特定オペレーションから
発信されているので、上記の手法 5) を使用している場合は、
サブルーチンをトレースしてそのシグナルを発している関数を特定する
必要があります。すべてのコードは、IEEE 754 のデフォルトを使用します。
つまり、すべてのゼロ除算をトラップしようとすると、
トラップしない場合にゼロ除算でも正しい結果を出すコードが中断されると
いうことです。
.SH 関連項目
\fBfpgetround\fR(3),
\fBfpsetround\fR(3),
\fBfpgetprec\fR(3),
\fBfpsetprec\fR(3),
\fBfpgetmask\fR(3),
\fBfpsetmask\fR(3),
\fBfpgetsticky\fR(3)   
\fBfpresetsticky\fR(3) - IEEE 浮動小数インタフェース
.SH 注釈
IEEE 754 とエクステンション p854 については、
1984 年 8 月に発行された、IEEE の雑誌『MICRO』を参照してください。
W. J. Cody らが「A Proposed Radix\- and Word\-length\-independent
Standard for Floating-point Arithmetic」という記事の中で
説明しています。Apple Macintosh の Pascal, C, BASIC のマニュアル
には、IEEE 754 の機能に関する分かりやすい説明があります。
IEEE の雑誌『COMPUTER vol. 14 no. 3』(1981 年 3 月) と 1979 年 10 月の
『ACM SIGNUM Newsletter Special Issue』の記事も役立ちますが、この
記事はのちに変更された標準仕様案に関係しています。