このセクションでは、libm および libsunmath の実装機能について説明します。
無限に正確な ??、および ?? でスケーリングされた三角関数を使用した引数還元
IEEE 形式と IEEE 以外の形式の間で浮動小数点データを変換するためのデータ変換ルーチン
乱数ジェネレータ
SPARC ベースのシステム上の libm および libsunmath 内の基本関数は、テーブル駆動および多項式/有理式近似アルゴリズムを使用して実装されます。これらのアルゴリズムは、パフォーマンスまたは正確性を向上させるためにリリース間で変更される可能性があります。x86 ベースのシステム上の libm および libsunmath 内の一部の基本関数は、x86 命令セットで提供される基本関数カーネル命令を使用して実装されます。その他の関数は、SPARC ベースのシステム上で使用されるのと同じテーブル駆動または多項式/有理式近似アルゴリズムを使用して実装されます。
テーブル駆動および多項式/有理式近似アルゴリズムはどちらも、libm 内の共通基本関数と libsunmath 内の単精度共通基本関数に対して、1 最終桁単位 (ulp) 以内まで正確な結果を提供します。 SPARC ベースのシステムでは、libsunmath 内の 4 倍精度共通基本関数は、2 ulp 以内まで正確な結果を提供する expm1l および log1pl 関数を除き、1 ulp 以内まで正確な結果を提供します。(これらの共通関数には、指数関数、対数関数、べき乗関数、およびラジアン引数の循環三角関数が含まれます。双曲線三角関数や高級超越関数などのその他の関数は正確性が低くなります。)これらの誤差制限は、これらのアルゴリズムの直接の分析によって得られました。また、ユーザーは、ucbtest パッケージ http://www.netlib.org/fp/ucbtest.tgzhttp://www.netlib.org/fp/ucbtest.tgz 内の netlib から入手可能な BeEF (Berkeley Elementary Function テストプログラム) を使用して、これらのルーチンの正確性をテストすることもできます。
[–??/4,??/4] の範囲外にあるラジアン引数の三角関数は通常、??/2 の整数倍を引いて引数を示された範囲に還元することによって計算されます。
?? は、マシンで表現可能な数値ではないため、近似する必要があります。最終的に計算される三角関数の誤差は、近似の ?? や丸めによる引数還元での丸め誤差と、還元された引数の三角関数の計算での近似誤差に依存します。かなり小さい引数の場合でも、最終的な結果の相対的な誤差より、引数還元誤差の方が大きくなることがあります。一方、かなり大きい引数の場合でも、引数還元による誤差が、その他の誤差よりは大きくならないことがあります。
すべての大きい引数の三角関数は本質的に不正確であり、すべての小さい引数の三角関数は比較的正確であるという、広く信じられている誤解があります。これは、マシンで表現可能な十分に大きい数値が ?? を超える間隔で区切られているという単純な観察に基づいています。
計算された三角関数の値が突然悪化するような固有の境界もなければ、不正確な関数値が役に立たなくなることもありません。引数還元が一貫して実行されている場合は、すべての基本的な同一性や関係が大きい引数に対して、小さい引数に対してと同様に保持されるため、引数還元が ?? への近似によって実行されていることにはほとんど気付きません。
libm および libsunmath 三角関数は、引数還元のために「無限に」正確な ?? を使用します。値 2/?? は 16 進数 916 桁に計算され、引数還元中に使用するルックアップテーブル内に格納されます。
関数 sinpi、cospi、および tanpi のグループ (表 16 を参照) は、範囲縮小によって導入される誤りを回避するために ?? で入力引数をスケーリングします。
libm および libsunmath には、IEEE 形式と IEEE 以外の形式の間で 2 進浮動小数点データを変換するために使用される柔軟なデータ変換ルーチン convert_external があります。
サポートされている形式には、SPARC (IEEE)、IBM PC、VAX、IBM S/370、および Cray で使用される形式が含まれます。
Cray 上で生成されるデータを取得する例や、関数 convert_external を使用して SPARC ベースのシステム上で想定される IEEE 形式にデータを変換する例については、convert_external(3m) のマニュアルページを参照してください。
32 ビット整数、単精度浮動小数点、および倍精度浮動小数点形式の均一擬似乱数を生成するための機能には、次の 3 つがあります。
addrans(3m) のマニュアルページで説明されている関数は、テーブル駆動加法的乱数ジェネレータのファミリに基づいています。
mwcrans(3m) のマニュアルページで説明されている関数は、キャリー付き乗算乱数ジェネレータに基づいています。また、これらの関数には、64 ビット整数形式の均一擬似乱数を提供するジェネレータも含まれています。
さらに、shufrans(3m) のマニュアルページで説明されている関数をこれらのいずれかのジェネレータと組み合わせて使用すると、擬似乱数の配列をシャッフルすることによってさらに高いランダム性を、それを必要とするアプリケーションに提供できます。64 ビット整数の配列をシャッフルするための機能はないことに注意してください。
各乱数機能には、1 回につき 1 つ (つまり、1 回の関数呼び出しで 1 つ) の乱数を生成するルーチンのほか、1 回の呼び出しで乱数の配列を生成するルーチンが含まれています。1 回につき 1 つの乱数を生成する関数は、表 30 に示されている範囲内の数値を提供します。
|
1 回の呼び出しで乱数の配列全体を生成する関数では、ユーザーは生成される数値の間隔を指定できます。例には、異なる間隔にわたって均一に分布された乱数の配列を生成する方法を示すいくつかの例が紹介されています。
addrans および mwcrans ジェネレータは一般に lcrans ジェネレータより効率的ですが、それらの理論はまだそれほど洗練されていません。『Random Number Generators: Good Ones Are Hard To Find』(S. Park 氏、K. Miller 氏共著、Communications of the ACM、1988 年 10 月) は、線形合同アルゴリズムの理論的な特性について説明しています。加法的乱数ジェネレータは、Knuth 氏の『The Art of Computer Programming』の第 2 巻で説明されています。