日本語 man コマンド類 (ja-man-1.1j_5) と日本語 man ドキュメント (ja-man-doc-5.4 (5.4-RELEASE 用) など) をインストールすると、以下のような man コマンド閲覧、キーワード検索が コンソールからできるようになります。
4.11-RELEASE-K, 5.4-RELEASE-K, 5.5-RELEASE-K, 6.0-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.2-RELEASE-K, 8.0-RELEASE-K は、プライベート版 (小金丸が編集してまとめたもの) ですが、 より多くの翻訳したファイルが含まれています。 (5.4-RELEASE-K から 6.4-RELEASE-K, 7.0-RELEASE-K から 7.2-RELEASE-K, 8.0-RELEASE-K は、全翻訳済み)
6.4-STABLE-K, 7.2-STABLE-K, 8.0-STABLE-K は現在、 作成中で日々更新されています。 最新の snapshots を元に作成しています。
MATH(3M) MATH(3M)
名称
math - 数学ライブラリ関数の導入
解説
この関数は、C の数学ライブラリ libm を構成します。リンクエ
ディタは、"-lm" オプションが指定されると、このライブラリを
検索します。この関数の宣言は、インクルードファイルで入手で
きます。
関数リスト
以下のそれぞれの倍精度浮動小数点数関数は、単精度関数と対に
なっ ており、名前が f で終わる関数は単制度浮動小数点数を扱
います。たとえば acos(double x) は、 浮 動 小 数 を 扱 う
acosf(float x) と対になっています。
名称 ページ 解説 エラー拘束 (ULP)
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 ベッセル関数 ???
May 6, 1991 1
MATH(3M) MATH(3M)
y1 j0.3m ベッセル関数 ???
yn j0.3m ベッセル関数 ???
注釈
カ リ フォ ルニア大学から 1985 年末に配布された 4.3 BSD で
は、上記の関数に 2 つのバージョンが用意されています。1 つ
は DEC VAX-11 ファミリのコンピュータの倍精度"D" フォーマッ
トで、もう 1 つは IEEE 754 標準のバイナリ浮動小数点数演 算
に 準 拠 した倍精度演算です。UNIX が誕生したときのものより
も、他のプログラムが正確で頑丈になったことから予想できるよ
う に、この 2 つのバージョンも、非常に似たような挙動を示し
ます。たとえば、これらのプログラムは、上の表の ulps の数以
内で正確です。ulp は、最終桁の単位です。これらのプログラム
は、かつての数学ライブラリ libm で発生していた異常状態を修
正しました。この異常状態が発生すると、以下のような結果が得
られていました。
sqrt(-1.0) = 0.0 であり log(-1.0)= -1.7e38
cos(1.0e-11) > cos(0.0) > 1.0
x = 2.0, 3.0, 4.0, ..., 9.0 のときに、pow(x,1.0) !=
x
pow(-1.0,1.0e10) が整数オーバフロー例外を起こしてい
た sqrt(1.0e30) と sqrt(1.0e-30) の計算が非常 に 遅
かった
し かしこの 2 つのバージョンには、説明しなければならない違
いがあります。以下に注意してください。
DEC VAX-11 D_floating-point:
これは、オリジナルの数学ライブラリ libm が開発されたフォー
マットであり、このマニュアルが原則的に依って立つフォーマッ
トです。これは、PDP-11 および初期の VAX-11 マシンの倍精 度
フォーマットです。1983 年以降の VAX-11 は、IEEE 倍精度フォ
ーマットにより近い、オプションの"G" フォーマットを備えてい
ます。初期の DEC MiroVAX には D フォーマットがなく、G 倍精
度のみが備わっています。
D_floating-point のプロパティ:
ワードサイズ: 64 ビット、8 バイト。基数: バイナリ。
精度: 56 ビット、10 進数で約 17 桁。
x と x' が連続した正の D_floating-point 浮動
小数点数 (1 ulp ずつ異なる) である場合は、
1.3e-17 < 0.5**56 < (x'-x)/x <= 0.5**55 <
2.8e-17
となる。
範囲: オーバフローしきい値 = 2.0**127= 1.7e38
アンダーフローしきい値 = 0.5**128= 2.9e-39
注意: この範囲は相対的に狭くなっています。
オーバフローが発生すると、計算は常に中断され
ます。
アンダーフローが発生すると、ゼロになります。
警告:
ア ンダーフローにより、x != y で x-y
= 0 となる可能性があります。同じよう
に、 x > y > 0 であっても、x*y = 0
May 6, 1991 2
MATH(3M) MATH(3M)
もしくは y/x = 0 ということが警告 な
しに発生してしまいます。
ゼロは曖昧に表現されます。
ハードウェアでは、2**55 通りのゼロの表現を受
理しますが、生成されるものは明らかな表現だけ
です。VAX には -0 がありません。
VAX アーキテクチャには無限 ( Infinity ) もありませ
ん。
予約オペランド:
ハードウェアは 2**55 通りを認識しますが、 生
成 されるものは 1 つだけです。予約オペランド
に対する浮動小数演算は、MOVF や MOVD でさ え
計算を中断するので、あまり使用されません。
例外:
ゼロ除算とオーバフローするオペレーションは不
正なオペレーションで、計算は中断されます。古
いマシンでは予約オペランドが作成され、計算が
中断されます。
丸め:
(PDP-11 では必ずしもそうとは言えませ ん が)
VAX でのすべての有理数演算 (+, -, *, /) は、
オーバフロー、アンダーフロー、ゼロ除算が発生
しない場合、ulp の半分以内に丸められます。丸
め誤差が ulp のちょうど半分である場合、丸 め
は 0 から離れます。
範囲が狭いことを別にすると、D_floating-point は、1960 年代
に設計されたものとしては優れたコンピュータ算術演算のひとつ
で す。D_floating-point のプロパティは、4.3 BSD で配布され
た VAX の基本的な関数に忠実に反映されています。オーバフ ロ
ーやアンダーフローが発生するのは、結果が範囲外になるか範囲
外に非常に近い場合のみで、その場合はオーバフローやアンダー
フローを起こす有理算術オペレーションと同じような動作をしま
す。同じように、log(0) と atanh(1) のような式は 1/0 のよう
に 動作し、sqrt(-3) と acos(3) は 0/0 のように動作します。
これらはすべて予約オペランドを作成し、計算は中断されます。
この状況については、それぞれのマニュアルページで詳しく説明
します。
このレスポンスは厳し過ぎるので、すべての浮動小
数演算の例外を適切に処理するように開発された、
柔軟で統一されたスキームで近い将来に置き換えら
れる予定です。
UNIX 用 4.3 BSD の新しい libm の関数を DEC の VAX/VMS ライ
ブラリと比較すると、一部の VMS 関数は多少速く、一部は多 少
精 度 が高く、一部はかなり例外に厳しくなって (pow(0.0,0.0)
と atan2(0.0,0.0) など) おり、ほとんどは、libm よりも多 く
のメモリを使用します。VMS コードは、大きいテーブルで補間し
て速さと精度を達成しています。libm コードは、将来はすべ て
が ROM に収まりそうなほど小型で相当工夫を凝らした式を使用
しています。
それより重要なことは、DEC が VMS コードを特許とみなし、 許
可 な く使用することを厳しく禁じているのに対し、4.3 BSD の
May 6, 1991 3
MATH(3M) MATH(3M)
libm コードは public domain を意図しているということです。
つまり、出所を常に明らかにして、ユーザがコードを使用した感
想を報告してコードの作者の研究に協力する限りにおいて、libm
コ ー ド は 自由にコピーできます。それゆえ、算術処理が VAX
D_floating-point に似ているマシンの UNIX ユーザ で あっ て
も、新しい libm よりも劣るものを使用する必要がないというこ
とです。
IEEE STANDARD 754 浮動小数点数算術演算:
この標準は、他のコンピュータ算術演算方式よりも広く採用され
てきています。以下のような多くのメーカが、この標準の一部の
バージョンに準拠した VLSI チップを製造しています。
Intel i8087, i80287 National Semiconductor 32081
Motorola 68881 Weitek WTL-1032, ... , -1165
Zilog Z8070 Western Electric (AT&T) WE32106.
この他にも、ソフトウェアによる実装 (Apple Macintosh は完璧
に それ) から、Hewlett-Packard 9000 シリーズの VLSI による
実装や、果ては ECL を駆使し、3 Megaflop を達成し た ELXSI
6400 まで極めて広い実装の幅を誇ります。他の企業の中には、
丸め、オーバフロー、アンダーフローなどの例外の処理でこの標
準 の方法に従わずに、IEEE 754 のフォーマットだけを採用して
います。DEC VAX G_floating-point フォーマットは、IEEE 754
Double フォーマットに非常に似ているので、上に挙げたほとん
どの初等関数の IEEE バージョンの C プログラムは、 MicroVAX
で実行するように簡単に変換できますが、わざわざ変換してやろ
うという人はいないようです。
4.3 BSD libm のコードのうち、IEEE 754 準拠マシン用の も の
は、National Semi. 32081 と WTL 1164/65 用になっています。
Intel チップや Zilog チップ、また は Apple Macintosh か
ELXSI 6400 でこのコードを使用する場合は、これらの企業が提
供するよりよいコード (無料になると思われる) か、上のコード
の 作 者 が 設 計したコードを使用することになります。atan,
cabs, cbrt, erf, erfc, hypot, j0-jn, lgamma, pow, y0-yn を
除 けば、Motorola 68881 は libm のすべての関数をチップに搭
載し、しかもより速く正確になっています。 Motorola, Apple,
i8087, z8070, WE32106 では、有効桁数 64 ビットを使用してい
ます。4.3 BSD の libm コードには、public domain を意図して
いるという長所があります。出所を常に明らかにし、ユーザがコ
ードを使用した感想を報告して作者の研究に協力すれ ば、 libm
コードは自由にコピーできます。算術演算が IEEE 754 に似てい
るマシンの UNIX ユーザは、新しい libm に劣るものを使用する
必要がないということです。
IEEE 754 Double-Precision のプロパティ:
ワードサイズ: 64 ビット、8 バイト、基数: バイナリ
精度: 53 ビット、(10 進数で) 約 16 桁。
x と x' が連続した正の倍精度浮動小数点数であ
る (1 ulp ずつ異なる) 場合は、
1.1e-16 < 0.5**53 < (x'-x)/x <= 0.5**52 <
2.3e-16 となる。
範囲: オーバフローしきい値 = 2.0**1024= 1.8e308
アンダーフローしきい値 = 0.5**1022= 2.2e-308
May 6, 1991 4
MATH(3M) MATH(3M)
オーバフローが発生すると、デフォルトで符号付
きの無限になります。 ア ン ダ ー フ ロ ー は
0.5**1074 = 4.9e-324 の倍数の整数のうち最も
近いものに段階的に丸められます。
ゼロは、+0 か -0 のようにあいまいに表現されます。
符号は乗算か除算で正しく変換され、符号付きゼ
ロ の加算で維持されます。しかし x が有限の場
合、x-x は +0 になります。0 の符号が問題にな
る 演 算 は、0 除算と copysign(x,+-0) のみで
す。とくに比較 (x > y, x >= y など) はゼロの
符 号 から影響を受けませんが、有限な値 x = y
である場合は、Infinity = 1/(x-y) != -1/(y-x)
= -Infinity になります。
Infinity は符号付きです。
Infinity をそれ自身か有限の数値に加算しても
無限は維持されます。Infinity の符号は乗算 と
除 算 で 正 し く 変 換 さ れ、 (有 限
値)/+-Infinity = +-0 (非 ゼ ロ 値))/0 =
+-Infinity になります。しかし、無限 - 無限,
無限 *0, 無限 / 無限は、0/0 や sqrt(-3) と同
様に不正な演算であり、NaN が生成されます。
予約オペランド:
2**53-2 通 りの予約オペランドがあり、すべて
NaN (Not a Number) と呼ばれます。一部は発 信
NaN と呼ばれ、それに対して浮動小数点演算を実
行するとトラップが発生します。値の欠落か未初
期化、または配列の存在しない要素をマークする
ために使用されます。その他は無発信 NaN と 呼
ばれます。これは不正演算の結果のデフォルト値
で、それ以後の算術演算に影響が波及します。 x
!= x である場合、x は NaN です。その他すべて
の論理演算 (x > y, x = y, x < y な ど) は、
NaN が関係する場合は偽になります。
注意: NaN は三分法を妨害します。
NaN が関係する場合、純粋な (不) 等値
演算ではなく順序付け比較を伴う論理演
算は偽になるだけでなく、不正演算とな
ります。
丸め:
デフォルトでは、すべての代数演算 (+, -, *,
/, sqrt) は、ulp の半分以内に丸められます。
丸め誤差が ulp のちょうど半分である場合、 丸
めた値の最下位有効ビットはゼロになります。通
常はこのような丸めが最適で、たと え ば 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 では、ゼロへの丸め、+Infinity への
丸め、-Infinity への丸めをプログラマが選択で
き るようになっています。最低でも 1.0e-10 か
ら 1.0e37 くらいまででは、バイナリと小数の変
May 6, 1991 5
MATH(3M) MATH(3M)
換に同じ種類の丸めを指定できます。
例外:
IEEE 754 では、5 種類の浮動小数例外が認識さ
れます。以下では、重要な順にその 5 種類を 挙
げます。
例外 デフォルトの結果
不正演算 NaN, または偽
オーバフロー +-無限
ゼロ除算 +-無限
アンダーフロー 段階的アンダーフロー
不精密 丸めた値
注意: 例外は、適切に処理されればエラーではあ
りません。例外を例外的なものにしてしま う の
は、すべての例を満たすデフォルトレスポンスが
ない場合です。逆に、デフォルトレスポンスがほ
とんどの例を満たす場合、それでも満たされない
例を、例外が発生するたびに演算を中断するとい
う手で正当化することはできません。
IEEE 754 では、それぞれの浮動小数例外のためにフラグ
を用意しています。このフラグは例外が発生するたび に
上 がり、プログラムでリセットするまで、上がった状態
で残ります。プログラムでは、フラグのテスト、保 存、
復元もできます。IEEE 754 には、デフォルトの結果が満
足の行くものでない例外にプログラムで対処する方法 と
して、以下の 3 つがあります。
1) 後 で 例 外の原因となる可能性がある条件をテスト
し、そのテスト結果に従って処理を変えて例外を 避
ける。
2) フ ラグをテストし、プログラムで最後にフラグをリ
セットしてから例外が発生したかどうかを 確 認 す
る。
3) 結 果をテストし、1 つの例外のみが発生する値であ
るかどうかを確認する。
警告: アンダーフローが発生したかどうかを確実 に
発 見するには、積や商がアンダーフローしきい値よ
りゼロに近いかどうかをテストするか、アンダー フ
ローフラグをテストするしかありません。(IEEE 754
では、和と差がアンダーフローを起こすことはあ り
ません。x != y である場合、x-y は完全に正確で、
値が小さくてもゼロではありません。) 段階的に ア
ン ダーフローを起こす積と商は、徐々に精度を失っ
てもゼロにはならないため、ゼロと比較しても (VAX
で実行する可能性がある)、ロスは明らかになりませ
ん。段階的にアンダーフローを起こした値をアン ダ
ー フローしきい値より大きい値と加算する場合、段
階的なアンダーフローで失われる桁は切り捨てら れ
る ので失われません。このため、通常の場合、段階
的なアンダーフローは無視できることがありま す。
ゼ ロにフラッシュされるアンダーフローでは、同じ
May 6, 1991 6
MATH(3M) MATH(3M)
ことが正しいとは限りません。
IEEE 754 に準拠するシステムでは、以下のような方法で
も例外に対処できます。
4) 異 常 終 了 (ABORT)。 このメカニズムでは、「ON
ERROR GO TO」のようなエラー処理ステートメントに
関 連 す る方法で処理する事がらとして、例外を前
もって分類します。言語が異なれば、このステー ト
メ ントの形式は変わりますが、次のような共通した
特徴があります。
-- 例外を起こした演算結果の値を代用し、式の途中 か
ら 計算を再開する方法がなくなります。例外の結果
は放棄されます。
-- エラー処理ステートメントがないサブプログラム で
は、 どのプログラムが呼び出してもそのサブプログ
ラムは例外のために異常終了し、エラー処理ステ ー
ト メントが見つかるまでサブプログラムが次々に呼
び出されるか、タスク全体が異常終了してメモリ の
ダンプが取られます。
5) 停止 (STOP)。対話型のデバッグ環境が必要になるこ
のメカニズムは、プログラマ用であってプログラ ム
向 きではありません。例外はプログラマの間違いの
兆候として前もって分類されます。例外が発生す る
と、 例外を起こしたオペレーションの近くで実行が
停止されるので、プログラマは、例外がどのよう に
発 生したのかを確認できます。多くの場合は、最初
の数個の例外は大きな問題ではなく、プログラマ は
そ れぞれの例外が発生するたびに、実行が停止され
なかったかのように実行を再開できます。
6) ... その他の方法については、この文書では説明 し
ません。
例 外処理には、範囲 (scope) という重大な問題があります。問
題の解決策は分かっていますが、人手不足のため、4.3 BSD の
libm で配布するときまでに完全に実現できませんでした。理想
的には、それぞれの初等関数を、次のような意味で分割せずに自
動的に動作させる必要があります。
i) 関数に提供したデータが値しない例外を発生させない。
ii) 発生したすべての例外をその関数で識別し、サブルーチン
では識別しない。
iii) 関数の定義が例外処理と関連しているにも関わらず、上記
5 つ の例外処理方法によって呼出し側プログラムを変更
し、小さな関数の内部処理を中断しない。
プログラマが、デバッグ済みサブプログラムをユーザが気付かな
いような小さなものに簡単にできるようになれば理想的です。し
May 6, 1991 7
MATH(3M) MATH(3M)
かし、小さな関数の 3 つすべての特徴をシミュレートするこ と
は、多くのテスト、保存、復元が伴うため、厄介な作業になって
います。現在、この不便さを改善する作業が進んでいます。
この作業が進むまで、libm の関数はそれほど小さくなりませ ん
が、以下の場合を除き、不適切な例外を発生させません。
オーバフロー / アンダーフロー
正しく計算した結果が、範囲内に収まっている場
合。
cabs, cbrt, hypot, log10, pow の不正。
エラーの偶発的な取り消しによって正確になった
場合。
その他の場合
不正演算は、以下のような場合にのみ発生します。
NaN 以外の結果が誤っていると思われる場合。
オーバフローは、以下のような場合にのみ発生します。
正しい結果が有限であるが、オーバフローしきい
値を越えている場合。
ゼロ除算は、以下のような場合にのみ発生します。
有限演算で、関数が無限の値を受けた場合。
アンダーフローは、以下のような場合にのみ発 生 し ま
す。
正しい結果がゼロではないが、アンダーフローし
きい値より小さい場合。
不正確は、以下のような場合にのみ発生します。
正しい結果の表現に、より広い範囲かより高い精
度が必要な場合。
バグ
信号が適切である場合、その信号はコードの特定オペレーション
から発信されているので、上記の手法 5) を使用している 場 合
は、サブルーチンをトレースしてその信号を発している関数を特
定する必要があります。すべてのコードは、IEEE 754 のデ フォ
ルトを使用します。つまり、すべてのゼロ除算をトラップしよう
とすると、トラップしない場合にゼロ除算でも正しい結果を出す
コードが中断されるということです。
関連項目
fpgetround(3), fpsetround(3), fpgetprec(3), fpsetprec(3),
fpgetmask(3), fpsetmask(3), fpgetsticky(3) fpreset-
sticky(3) - IEEE 浮動小数インタフェース
注釈
IEEE 754 とエクステンション p854 については、1984 年 8 月
に発行された、IEEE の雑誌『MICRO』を参照してくださ い。 W.
J. Cody らが「A Proposed Radix- and Word-length-indepen-
dent 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』 の記事も役立ちますが、この記事はのちに変更された標
準仕様案に関係しています。
May 6, 1991 8