このマニュアルは,MPFR(Multiple Precision Floating-point Reliable)ライブラリ Version 4.0.2のインストール方法,及び,使用方法を記述したものです。
Copyright 1991, 1993-2019 Free Software Foundation, Inc.
本マニュアルの複写,配布,改変は,GNU Free Documentation License Version 1.2以降の 条項の元で許可されています。但し,不変の節,表紙の文,裏表紙の文を改変して はいけません。本マニュアルにはGNU Free Documentation Licenseも入っています。
• Copying: | MPFRの著作権(LGPL). | |
• Introduction to MPFR: | MPFRの簡単な紹介 | |
• Installing MPFR: | MPFRライブラリの設定とコンパイル方法 | |
• Reporting Bugs: | 有用なバグ報告の書き方 | |
• MPFR Basics: | MPFRユーザなら押さえておくべき事柄 | |
• MPFR Interface: | MPFR関数とマクロ | |
• API Compatibility: | 以前のMPFRとのAPI互換性 | |
• MPFR and the IEEE 754 Standard: | MPFRとIEEE754浮動小数点演算標準規格 | |
• Contributors: | MPFR開発貢献者一覧 | |
• References: | 参考文献 | |
• GNU Free Documentation License: | ||
• Concept Index: | ||
• Function and Type Index: |
Next: Introduction to MPFR, Previous: Top, Up: Top [Index]
GNU MPFRライブラリ(MPFRと略す)は フリーです。フリーとは,万人が自由に使用でき,自由な基盤の上で,再配布も 自由にできるという意味です。 本ライブラリはパブリックドメインではありません。つまり,著作権で守られており, 再配布には制限があります。しかしその制限は,良き協力者たる市民が行おうとする全ての 行為を許容するように設計されています。許されないのは, あなたから入手したあらゆるバージョンの本ライブラリを,更に広く共有する行為を妨害することだけです。
特に,我々は次のことを確認したいと考えています。あなたは本ライブラリのコピーを手放す権利があり, 欲しい時にソースコードなどを受け取り,新しいフリーなプログラムを作るために本ライブラリの 改変を行ったり,一部を利用したりすることができる,ということを知っているのです。
万人が上記の権利を持っているということを知らしめるため,我々は,あなたが,他の人達からこれらの権利を剥奪することを禁止します。例えば,あなたがGNU MPFRライブラリのコピーを配布 するのであれば,それを受け取った人達にも,あなたが有する全ての権利を与えなければなりません。 そして,受け取った人たちもまた,元のソースコードを入手できるということを確認しなければなりません。 更に,あなたは彼らにそのことを周知しなくてはなりません。
また,我々自身を保護するため,GNU MPFRライブラリは無保証であることを周知させなくてはなりません。 本ライブラリを改良して放出した場合,我々は,それがもとの配布物とは別物であることを知って頂きたいと思います。 そうすることで,改良の結果生じた諸問題によって我々の評判が貶められることはなくなります。
GNU MPFRライブラリのライセンスの正確な著作権の条項については, ソースコードに付随する劣等GPL(Lesser General Public License)に書いてあります。COPYING.LESSERファイルを参照して下さい。
Next: Installing MPFR, Previous: Copying, Up: Top [Index]
MPFRはポータブルなCライブラリで,任意精度の浮動小数点演算を行います。その基盤ライブラリとしてGNU MP(GMP)を使用しています。 MPFRの目的は,緻密な方針に基づいた浮動小数点数クラスを提供することにあり,下記に示すように,他の任意精度浮動小数点ソフトウェアとは異なる特徴があります。
mp_bits_per_limb
(現在のプロセッサ上では普通は64ビット)
に依存せずに確定する,ということです。但し,忠実丸め方式(効率的かつ高精度な丸め方式,faithful rounding)については
計算環境に影響される可能性があります。計算環境における丸めモードや丸める精度桁数には影響されません。
MPFRを使用して53ビットの精度桁数を設定し,4つの丸めモードのいずれかを使用した場合,
四則演算と平方根を用いたハードウェアの倍精度(double precision)浮動小数点演算(例えばCのdouble
型を使い,ISO C99標準規格のAnnex Fを厳守して実装したCコンパイラを使用し,FP_CONTRACT
プラグマをOFF
にして実行) による計算結果と
全く同じものを,MPFRは再生できます。 但し,MPFRのデフォルトの指数部は倍精度に比して大幅に広い,非正規化数はサポートしていない(エミュレートは可能),という違いはあります。
本バージョンのMPFRは,GNU Lesser General Public License Version 3.0以降の条項の元にリリースされています。 MPFRにフリーでないプログラムをリンクすることも可能ですが,この非フリーのプログラムを配布する際には,リンク元のプログラムにMPFRのソースコードと,改良されたMPFRライブラリとリンクするための方法も一緒に配布する必要があります。
まずMPFR Basicsは読んで下さい。MPFRのインストールを自力で行う必要がある場合は, Installing MPFRにも目を通して下さい。MPFRライブラリの使用時にはMPFR Interfaceが参考になるでしょう。
本章以降の記述は後々の参照用ですが,一通り目を通しておくと良いでしょう。
Next: Reporting Bugs, Previous: Introduction to MPFR, Up: Top [Index]
MPFRライブラリは,GNU/Linuxディストリビューションには予めインストールされていることが
多くなりました。しかし,開発用に必要なmpfr.h等のファイルが入っていないことは
ままあります。MPFRがフルでインストールされているかどうかを確認するには,/usr/include
にmpfr.hがあるかどうかをチェックしたり,#include <mpfr.h>
(mpfr.hの
置き場所は色々です)と書いてある小さいプログラムをコンパイルしたりします。例えば,下記の
プログラムをコンパイルしてみましょう。
#include <stdio.h> #include <mpfr.h> int main (void) { printf ("MPFR library: %-12s\nMPFR header: %s (based on %d.%d.%d)\n", mpfr_get_version (), MPFR_VERSION_STRING, MPFR_VERSION_MAJOR, MPFR_VERSION_MINOR, MPFR_VERSION_PATCHLEVEL); return 0; }
上記のプログラムは,下記のようにしてコンパイルします。
cc -o version version.c -lmpfr -lgmp
さすれば,次のような記述から始まるエラーが出るかもしれません。
version.c:2:19: error: mpfr.h: No such file or directory
このエラーが出たら,MPFRは多分ちゃんとインストールされていません。もしこの プログラムが実行できれば,インストールされているMPFRのバージョン番号が表示される 筈です。
MPFRがインストールされていなかったり,別バージョンのMPFRをインストールしたい 時には,次の節に示す手順でやってみて下さい。
この節では,UNIXシステムにMPFRをインストールするための手続きを説明します。 詳細はINSTALLファイルをご覧下さい。
以上の準備ができたら,MPFRのビルド用ディレクトリで,下記のコマンドを実行しましょう。
これによって,ビルドの準備が完了し,貴方のシステムにふさわしいオプションがセットアップされます。 インストールディレクトリ(デフォルトは/usr/local)や,スレッドのサポートなど,デフォルトとは 異なるオプションを指定することも可能です。詳細についてはINSTALLファイルや,‘./configure --help’ の出力結果をご覧下さい。エラーメッセージが出た時もこの辺りの記述を参照して下さい。
このコマンドでMPFRをコンパイルし,ライブラリアーカイブファイルであるlibmpfr.aを生成します。 大方の環境では,動的ライブラリ(dynamic library)も一緒に生成されます。
このコマンドは,MPFRのビルドが正常に行われたかどうかを確認します。 確認に失敗した時は,どこでどのようにコケているかを tests/test-suite.logファイルで調べることができます。このファイルの中身を 自動的に出力したい時には,予め‘VERBOSE’環境変数を1にセットしてから‘make check’ を実行します。例えば次のように打ち込んで下さい。
‘VERBOSE=1 make check’
コケた時にはその要因が既知のものかどうかを知りたいと思うのが人情ですよね?(つか,調べて下さいな)。 未知の要因によるものでしたら,MPFRメーリングリスト ‘mpfr@inria.fr’に報告をお願いします。詳細はReporting Bugs をご覧下さい。
これを実行することで,mpfr.hやmpf2mpfr.hといったヘッダファイルを /usr/local/includeディレクトリへ,ライブラリファイル(libmpfr.aや動的ライブラリファイル等 )を/usr/local/libディレクトリへ, mpfr.infoファイルは /usr/local/share/infoディレクトリへ,その他のドキュメントファイルを/usr/local/share/doc/mpfrディレクトリへそれぞれコピーします。‘--prefix’オプションがconfigure実行時に指定されていれば, このprefixディレクトリ(‘--prefix’に続く引数として与える)を/usr/localの代わりに使用します。
以上で示したもの以外にも有用なmakeオプションがあります。
このMPFRマニュアルのinfo形式ファイルの生成,もしくは更新。mpfr.infoができます。
このファイルはMPFRアーカイブに含まれています。
このマニュアルのPDFバージョンが生成されます。ファイルはmpfr.pdfです。
このマニュアルのDVIバージョンの生成。ファイルはmpfr.dviです。
このマニュアルのPostscriptバージョンの生成。ファイルはmpfr.psです。
このマニュアルのHTMLバージョンの生成。複数ページが生成されて doc/mpfr.htmlディレクトリに格納されます。一つのHTMLファイルにまとめたい場合は, ‘doc’ディレクトリに移動し,makeコマンドではなく,‘makeinfo --html --no-split mpfr.texi’と打ち込んで下さい。
全てのオブジェクトファイルとアーカイブファイルを消去します。設定用のファイル類はそのまま残ります。
配布ファイル以外,すべての生成ファイルを消去します。
‘make install’でインストールされたすべてのファイルを消去します。
何かしらトラブった時には,バグだと騒ぎ立てる前にINSTALLファイル,特に,「問題が起こった時には」の節を 熟読して下さい。 MPFRに限らず,ユーザー側でヘンな設定を行っているためにトラブルが発生してしまうことがあります。 MPFRサイトのFAQ https://www.mpfr.org/faq.htmlにも,トラブルについての記載があります。
トラブルの報告はMPFRのメーリングリスト‘mpfr@inria.fr’宛にお願いします (Reporting Bugs 参照)。 修正済みのバグは, MPFR 4.0.2のWebページhttps://www.mpfr.org/mpfr-4.0.2/に掲載されています。
MPFRの最新バージョンは https://ftp.gnu.org/gnu/mpfr/ もしくは https://www.mpfr.org/から入手できます。
Next: MPFR Basics, Previous: Installing MPFR, Up: Top [Index]
MPFRライブラリにバグを発見したと思ったら,まずはMPFR 4.0.2のWebページhttps://www.mpfr.org/mpfr-4.0.2/ と,FAQ https://www.mpfr.org/faq.htmlを見て下さい。 多分,それは既知のバグで,それに関係したものを見つけたということかもしれません。 バグ情報については,MPFRのメーリングリストのアーカイブ https://sympa.inria.fr/sympa/arc/mpfrにもあります。 その上で,既知のものではないと判断したら,調査の上,報告して下さい。 我々開発陣は,このMPFRライブラリを作り上げ,貴方に提供している訳です。貴方が見つけたバグの報告をお願いしても罰は当たりませんよね? 報告の際には,以下の事柄を守って下さい。
まず,我々にも再現できるようなバグの事例をきちんと報告して下さい。例えば,MPFRだけを 使用した単独の小さいプログラムと,その実行方法を示して下さい。
どこがおかしいのかを説明することも必要です。クラッシュする,結果が正しくないという ことでしたら,どんな場合にどのようにすればそれが起きるのか,ということを示して下さい。
バグ報告には,コンパイラのバージョン番号も記載して下さい。これは ‘cc -V’や,GCCの場合は‘gcc -v’で取得できます。また,‘uname -a’の出力結果と MPFRのバージョン番号(GMPのバージョンが分かるのであればそれも)をお知らせ下さい。 ‘make’や‘make check’の実行時にエラーが出るのであれば,config.logファイルも バグ報告に添付して下さい。テスト時にエラーが出る場合は,tests/test-suite.logファイルも 添付して下さい。
貴方のバグ報告が良いものであれば,我々開発陣は全力でその解決に努力しますが,そうでなければ ,「もう少しまともな報告をしてよね」ぐらいの文句は言ってオシマイになるかもしれません。
バグ報告はMPFRのメーリングリスト‘mpfr@inria.fr’に送って下さい。
このマニュアルの記述が良く分からない,不正確な記述がある,言語不明瞭故に改良求む,ということでしたら, バグ報告同様,MPFRのメーリングリストにその旨伝えて下さい。
(訳注:日本語訳についてのご意見は‘kouya.tomonori@sist.ac.jp’にお寄せ下さい。)
Next: MPFR Interface, Previous: Reporting Bugs, Up: Top [Index]
• Headers and Libraries: | ヘッダファイルとライブラリファイル | |
• Nomenclature and Types: | 用語とデータ型 | |
• MPFR Variable Conventions: | MPFR変数のデータ変換 | |
• Rounding Modes: | 丸めモード | |
• Floating-Point Values on Special Numbers: | 特殊な値を表現する浮動小数点数 | |
• Exceptions: | 例外 | |
• Memory Handling: | メモリ制御 | |
• Getting the Best Efficiency Out of MPFR: | MPFRからパフォーマンスを引き出す術 |
Next: Nomenclature and Types, Previous: MPFR Basics, Up: MPFR Basics [Index]
MPFRを使用するにあたり,必要となる変数や宣言は全て mpfr.hに含まれており,CでもC++でもそのままインクルードできるようになっています。 MPFRライブラリを使用するプログラムは例外なく下記のようにこのファイルをインクルードして下さい。
#include <mpfr.h>
MPFRの関数ではFILE *
型の引数を利用しており,このプロトタイプ宣言は<stdio.h>
で行われているので,mpfr.hの前で,一緒にインクルードしておきましょう。
#include <stdio.h> #include <mpfr.h>
同様に,mpfr_vprintf
関数等でva_list
型引数を利用しているため,<stdarg.h>
(あるいは <varargs.h>
)も
このデータ型のプロトタイプ宣言を行うためにインクルードしておく必要があります。
また,intmax_t
を使用する関数に対しては必ず
<stdint.h>
もしくは <inttypes.h>
を,mpfr.hより先にインクルードして下さい。
これによって,mpfr.hでこれらの関数のプロトタイプ宣言が有効になります。
更に,いくつかの環境下では(特にC++コンパイラで使用する場合),
ユーザー側で
MPFR_USE_INTMAX_T
を (ポータブルにしたいなら特に),mpfr.hより先に
定義しておかなければいけません。あるいは,コマンドラインで
-DMPFR_USE_INTMAX_T
として定義しておくことも可能です。
[注記] mpfr.hファイル,もしくはgmp.h (mpfr.h内部で使用)
が,他のヘッダファイルでも重複してインクルードされるようであれば,
<stdio.h>
や <stdarg.h>
(もしくは <varargs.h>
)
は,mpfr.h や gmp.hより前でインクルードすべきです。
あるいは,MPFR_USE_FILE
(MPFR I/O 関数で必要) や
MPFR_USE_VA_LIST
(va_list
パラメータを使用するMPFR関数で必要)を
mpfr.hより前で定義しておくという手もあります。
つまり,mpfr.hをインクルードするような独自のヘッダファイルを作るのであれば,
後者の方法を使う必要があるわけです。
MPFRのマクロを呼び出す際には,使用してはいけないキーワード(現時点ではdo
,
while
,sizeof
など)と同じ名前のマクロを定義しないようにしましょう。
mpfr.hをインクルードする前に,MPFR_USE_NO_MACRO
マクロを被せた
関数を使ったMPFRマクロの使用は控えましょう。このマクロはデバッグ用で,普通は使いません。
あるマクロを使うことで,警告オプション
指定時にはコンパイラがニセの警告を出し,プロトタイプ宣言のチェックを
妨げる可能性が出てくるからです。
MPFRを利用するプログラムは,必ずlibmpfrライブラリファイルと libgmpライブラリファイルをリンクしなければなりません。UNIXコマンドラインでリンクする際には ‘-lmpfr -lgmp’ (この順序でリンクすること)と指定します。GCCの場合は下記のように指定してリンクします。
gcc myprogram.c -lmpfr -lgmp
MPFRのビルドにはLibtoolを使用しているため,それを利用することも可能です。詳細は GNU Libtool参照 のこと。
MPFRが標準的ではない所にインストールされている場合は,‘C_INCLUDE_PATH’や‘LIBRARY_PATH’ といった環境変数にそのパスを設定したり,コンパイラの‘-I’ や ‘-L’ オプションで適切な ディレクトリを指定することで対応できます。共有ライブラリの場合は,ランタイムライブラリパス(‘LD_LIBRARY_PATH’等)の設定も行って おく必要があります。その他のインストールに関する情報についてはINSTALLファイルをご覧下さい。
その他,下記のように,‘pkg-config’ (MPFR 4.0から用意されている‘mpfr.pc’ファイル)を使用することもできます。
cc myprogram.c $(pkg-config --cflags --libs mpfr)
‘MPFR_’や‘mpfr_’といった語句から始まる関数,マクロ,定数等はMPFR で 予め定義されているものになります。従って,MPFRを利用するソフトウェアは,通常はこれらの文字列の使用は避け るようにして下さい。
Next: MPFR Variable Conventions, Previous: Headers and Libraries, Up: MPFR Basics [Index]
浮動小数点数(floating-point number)(短くfloatとも称します)は
2を基数とする浮動小数点数を表現するオブジェクトであり,符号部,任意長の正規化された有効小数部(仮数部とも呼ぶ),指数部(固定長の整数)で構成されているものを,正規化数(regular number)と呼びます。IEEE754規格と同様,MPFRの浮動小数点数も正規化数以外に,3種類存在します。符号付きゼロ,符号付き無限大,非数(NaN)がそれにあたります。NaNは浮動小数点オブジェクトのデフォルト値で,ゼロ割るゼロ,+無限大引く+無限大といった演算の結果としても使用されます。特に明記されていなければ,NaNの符号部は不定です。IEEE754規格とは異なり,MPFRには一種類のNaNしかありませんし,非正規化数も存在しません。それ以外はほぼIEEE754規格に準拠していますが,多少異なるところがあるやもしれません。
MPFR浮動小数点数オブジェクトのCデータ型は mpfr_t
で,要素を一つだけ持つ構造体の配列として定義されています。こうすることで,配列の引数として渡される時にはこの配列へのポインタとして扱われるからです。このポインタはmpfr_ptr
というCデータ型として定義されています。
精度桁数(precision)は,浮動小数点数の有効小数部のビット数を意味します。Cのデータ型としてはmpfr_prec_t
を使用します。
精度桁数はMPFR_PREC_MIN
から
MPFR_PREC_MAX
までの範囲の任意の整数値に設定できます。現在の実装ではMPFR_PREC_MIN
は1となっています。
[警告] MPFRは内部で精度桁数を増やして計算する必要があります。こうすることで,正確な演算結果(特に,正しく丸めたもの)を返すことができる訳です。従って,精度桁数をMPFR_PREC_MAX
付近に設定しないようにして下さい。さもないと,アサーションエラーを誘発してしまいます。また,使用環境のメモリ限度目一杯まで使用することは避けて下さい。プログラムが強制終了されたり,クラッシュしたり,Cプログラムによっては訳の分からない挙動を引き起こすことになりかねません。
指数部(exponent)は正規化されている通常の浮動小数点数のパーツの一つです。
Cのデータ型はmpfr_exp_t
となります。有効な指数部の範囲は元となるデータ型が扱える範囲に制限されます。また,Exception Related Functionsで説明している通り,指数部の範囲をグローバルに設定することも可能です。3種類の特殊な浮動小数点値は指数部を保持しません。
丸めモード(rounding mode)は,浮動小数点演算結果を丸める方式を定めるものです。丸めは,演算結果がそのまま格納先の変数に収まり切れない時に実行されます。丸めモードを表わすCのデータ型はmpfr_rnd_t
です。
MPFRはグローバルに,もしくはスレッドごとにフラグを保持しており,サポートしている例外をここで判別します(Exceptions)。 フラグのCデータ型は,複数のフラグやビットマスクを一括して表現できるようになっています。
Next: Rounding Modes, Previous: Nomenclature and Types, Up: MPFR Basics [Index]
MPFR変数を割り当てる前に,初期化のための関数を呼び出す必要があります。変数が用済みになった際には,当該変数を消去する関数を呼び出す必要があります。 変数の初期化は一回だけにしておきましょう。何度も初期化しようとすると,その間に消去関数を呼ぶ必要が出てきます。一度初期化された変数に対しては何度でも値を代入することができます。
動作が遅くならないよう,変数の初期化と消去をループ内で繰り返さず,ループに入る前に一度だけ初期化を行い,ループを抜けてから変数を消去するようにしましょう。
MPFR変数用に追加的なメモリスペースを確保する必要はありません。どんな精度桁数の変数でも,仮数部は固定サイズで確保されます。従って,精度桁数の変更,初期化,再初期化等をしない限り,変数が有効である間は使用メモリ量は変化しません。
一般に,全てのMPFR関数の引数の並び順は,前の方が出力用,その後ろが入力用となります(訳注:LAPACKやBLASとは真逆)。これは,代入演算子に倣った作法です。
MPFRの場合,同一の関数の引数として入力用・出力用に同じ変数を指定することも可能です。例えば,浮動小数点数の乗算を行う代表的な関数は
mpfr_mul
ですが,これはmpfr_mul (x, x, x, rnd)
という指定を行っても全く問題ありません。
この場合は,xの二乗を丸めモードrnd
の下で計算し,その演算結果をxに書き戻します。
Next: Floating-Point Values on Special Numbers, Previous: MPFR Variable Conventions, Up: MPFR Basics [Index]
MPFRがサポートする丸めモードは以下の通りです。
MPFR_RNDN
: 最近接値への丸め (IEEE 754-2008規格のroundTiesToEvenに相当),
MPFR_RNDZ
: ゼロ方向への丸め(切り捨て) (IEEE 754-2008規格のroundTowardZeroに相当),
MPFR_RNDU
: +∞方向への丸め (IEEE 754-2008規格のroundTowardPositiveに相当),
MPFR_RNDD
: -∞方向への丸め (IEEE 754-2008規格のroundTowardNegativeに相当),
MPFR_RNDA
: ゼロから遠ざかる丸め
MPFR_RNDF
: 忠実丸め(faithful rounding)。現在まだ試験的なもので,使用できるのは基本演算(加減乗除算,2乗,平方根)や,本文書で言及されているMPFRの一部の演算だけです。他の演算でもこの丸めモードを使用できるかもしれませんが,正しい動作は保証致しかねます。テストコードで問題が起これば対処はしますが,目視でのチェックは今のところしていません。もし問題があればバグとして報告して頂ければ,対処することは可能でしょう。
‘最近接値への丸め’(RN)モードの挙動はIEEE 754規格に定められている通りです。浮動小数点数として表現できる数のちょうど中間地点の値の場合は,最小有効ビット(LSB, Least Significant Bit)がゼロになる方の値に丸められます。例えば,2.5という値の場合は,2進数では(10.1)と表現されますが,2ビットに収めようとする場合,(11.0) = 3ではなく,(10.0) = 2の方を選択します。このルールは,Knuthの"The Art of Computer Programming" Vol.2の4.2.2節(訳注: アスキー・メディアワークスの日本語訳ではP.223)で解説されている ドリフト現象を防ぐために設けられています。
MPFR_RNDF
モードの場合,MPFR_RNDD
モード時の値になるか,
MPFR_RNDU
モード時の値になります。
計算結果がピッタリ収まる場合,つまり,演算結果が丸めなしで正しく表現できる場合は,
その値がそのまま返されます。従って,丸めの結果は2種類存在し,アンダーフローやオーバーフロー
が起こらなければ,丸められた値の誤差は厳格に1ULP(Unit in Last Place)未満で収まります。
MPFR_RNDF
モードの場合, 返り値の三種値(ternary value, 定義は後述)と不正確フラグ(inexact flag, 定義はフラグの解説時にまとめて述べる)
は不定,ゼロ除算フラグ(divide-by-zero
flag)は他の丸めモードと同様に設定,アンダーフローフラグとオーバーフローフラグは,丸めた値がMPFR_RNDD
モード時のものになるか,MPFR_RNDU
モード時のものになるかにより,相応するものが設定されます。
この丸めの結果は再現できないことがあり得ます。
MPFRが提供する関数の大部分は,最初の引数に演算結果を格納し,2番目の引数以降に入力値を与え,
最後の引数で丸めモードの指定を行い,関数の返り値はint
型,という形式になっています。この返り値を
三種値(tenary value)と称します。演算結果として格納される値は正しく丸められた(correctly rounded)もの
となっています。つまり,MPFRは,無限桁計算で得られる結果を,この変数の指定精度ビット数に収まるように丸めて返す,
という処理を行う訳です。入力値には誤差はない(指定精度ビット数に収めても変化しない)ものとして扱います。
結果として,ゼロではない実数を丸めた場合の誤差は,最近接値丸めモードの場合は1/2 ulp(unit in the last place)以下 となり,その他の丸めモードでは1ULP未満となります(このULPは,丸めた後の値の有効ビットに対するものとなる)。
特に記述がなければ,int
型の返り値を取る関数は三種値を返します。
この返り値がゼロの時は,先頭の変数に格納される演算結果は丸めの必要のない正確な値であることを示しています。
返り値が正の値の時(負の値の時)は,格納される値は正確な値よりも大きくなっている(小さくなっている)ことを表わしています。
例えば,MPFR_RNDU
モードの時は,返り値の三種値は常に正の値となり,例外として,丸めの必要のない場合のみ,ゼロが返ってきます。
無限大(∞)になる場合はオーバーフローを起こしているので不正確な値と判断し, それ以外の場合は正確な値と見なします。
非数(NaN, Not-a-Number)は常に正しい値とします。返り値の三種値の逆符号の値は必ずint
型として表現できるようになっています。
特に記述がなければ,特別な場合に限り(acos(0)
など),返り値として1
(もしくは本マニュアル記載の指定値)となる
関数は,その値が現時点の指数部の許容範囲内に収まらない場合はオーバーフロー,もしくはアンダーフローを発生させることになります。
Next: Exceptions, Previous: Rounding Modes, Up: MPFR Basics [Index]
この節では,MPFR関数が返す特殊な浮動小数点数値(mpfr_t
型として表現される)について解説します。ここで,「返す」とは,出力用の引数オブジェクトに格納される演算結果の値のことを意味します。関数の返り値そのものはint型の三種値(-1, 0, 1)なので,混同しないようにして下さい。
複数の値を返す関数(例えばmpfr_sin_cos
関数など)はこの規則が複数の値の格納先ごとに適用されます。
MPFRの関数には複数の入力引数を必要とするものがあります。この入力引数一つ分は,MPFR数値からなる入力値集合への対応付けを表わしています。 入力値集合から非数を除くと,この写像が指し示す先は拡張された実数,つまり両端の無限大(±∞)を含む拡張実数集合と見なせます。
入力データが目的の数学関数の定義域内に収まっていれば,関数の返り値は“丸めモード”の節で解説している方式で丸められます (符号付きゼロの場合は後述)。定義域外の場合は,各MPFR関数ごとに本マニュアルの関数の解説(MPFR Interface)通りに処理し,特に言及がなければ本節に述べた一般的なルールで処理されます。
入力データが数学関数の定義域外であっても,正負無限大も含む拡張実数集合に収まっていて,かつ,連続的に拡張できる場合,関数の演算結果は極限値となります。例えば,定義域が(+Inf, 0)のmpfr_hypot
関数は+Infを返します。但し,このルールを使っても,mpfr_pow
関数は(1,+Inf)では定義できません。この理由は,1に収束するx_n
と,+Infに発散するy_n
を組み合わせたx_n
, y_n
という数列を考えてみれば分かります。この時,x_nはy_nに収束
となりますが,nを無限大に飛ばすと,任意の正の値に収束させることができるからです。
入力値が数学関数の定義域の端っこだったり,+0 (もしくは-0)だったりすると,
数学的には入力値の0への右極限(もしくは左極限)を考える必要が出てきます。
極限値が存在しない場合,例えば,-0に対する
mpfr_sqrt
関数やmpfr_log
関数の極限値などは,MPFR関数の実装次第で演算結果が
変わってきますが,例えば入力値±
0に対する
mpfr_log
関数は常に-Infを返す,というように,前述のような規則に則った決め方をしなければなりません。
結果が0になる時は,ゼロの符号は,入力値が定義域に存在しない状況での極限値を考慮して
決定します。0より大きい(小さい)ところからの極限値は+0 (-0)になります。
例えば,-0を引数として与えたmpfr_sin
関数の値は-0となり,
引数が1の時のmpfr_acos
関数の値は,丸めモードに関わらず+0になります。
その他の場合は,MPFR関数の実装によって符号が決定されます。例えば,-0 と +0を
入力値とするmpfr_max
関数の値は+0になります。
入力値が定義域外にある場合の値はNaNになります。
例えば,-17を入力値とするmpfr_sqrt
関数はNaNを返します。
入力値がNaNの時は,定数関数である場合を除いて,結果もNaNになります。 その辺りのことはMPFR Interfaceに明示してあります。
例)(NaN,0)という入力に対してmpfr_hypot
関数はNaNを返しますが,
入力が(NaN,+Inf)であれば+Infを返します。このことはSpecial Functionsのところで解説しています。
入力値xが有限値であれ無限大であれ,mpfr_hypot
関数は(x,+Inf)という入力に対しては
+Infを返します。
Next: Memory Handling, Previous: Floating-Point Values on Special Numbers, Up: MPFR Basics [Index]
MPFRは,サポートする例外ごとにグローバルフラグ(もしくはスレッドごとのフラグ)を定義しています。フラグは2のべき乗を計算するマクロで,それぞれのフラグと例外を関係づけています。複数のフラグやマスクを一つにまとめても特定できるよう,個別のマクロとのORを取ることで,例外を特定できるようになります。
フラグは,クリアしたり(lowered), 立てたり(raised), Exception Related Functionsに解説してある関数で状態を確認することができます。
サポートする例外の一覧を下記に示します。カッコ内は各例外に関係するマクロを意味します。
MPFR_FLAGS_UNDERFLOW
):
アンダーフローは,計算結果の真値がゼロではない実数で,指数部長を制限せずに丸めた結果,現時点での
最小指数部値より小さい指数部になった時に発生します。最近接値への丸めの場合,ちょうど中間地点
の値の場合は,ゼロ方向に丸められます。
[注記] アンダーフローの定義はこれだけに限りません。MPFRは丸めの後でアンダーフローを 関知しますが,丸めの前のアンダーフローというものも定義可能です。 例えば,7に2の e-4乗を掛けたもの を求める関数を考えましょう。ここでeは 最小の指数部とし,仮数部は1/2と1の間にあるものとします。 格納先は2ビットの精度桁数しかないものとし,正の無限大方向への丸めを考えます。 真値の指数部はe-1となります。丸め処理の前にアンダーフローが起きると, この関数はアンダーフローを生成します。e-1は現在の指数部範囲の 外側になります。しかしながら,MPFRは最初に指数部の範囲を限定せずに丸めを行って考えます。 正確に計算結果を2ビット精度桁数では表現できませんので,ここでは0.5に2のe乗を掛けたもの は現在の指数部の範囲で表現できます。従って,MPFR におけるアンダーフローは発生しません。
MPFR_FLAGS_OVERFLOW
):
オーバーフローは,計算結果の真値が非ゼロの実数で,指数部長を制限せずに丸めた結果,現在の
指数部の最大値より大きい指数部になる時に発生します。最近接値への丸めの場合は,無限大を返します。
[注記] アンダーフローとは違い, オーバーフローの定義はこれ一つです。
MPFR_FLAGS_DIVBY0
):
有限値の入力に対して,演算結果が無限大になった時に発生します。
MPFR_FLAGS_NAN
):
NaN例外は,計算の結果がNaN になる場合に発生します。
MPFR_FLAGS_INEXACT
):
不正確例外(inexact exception)は,丸め誤差が生じる時に発生します
MPFR_FLAGS_ERANGE
):
範囲エラーは,MPFR数を返さない関数(例えば比較関数,整数への変換関数など)
が不正な結果を返す場合(mpfr_cmp
関数の引数がNaNだったり,整数変換関数において,変換先のデータ型に収まらない場合など)に発生します。
更に言うと,これら全てのフラグから成るグループはMPFR_FLAGS_ALL
マクロで
表現することができます。MPFRの将来のバージョンで新しいフラグが追加されても,
このマクロにはそれが追加される予定です。
ISO C99規格との相違点は下記の通りです。
Next: Getting the Best Efficiency Out of MPFR, Previous: Exceptions, Up: MPFR Basics [Index]
MPFR関数の中にはキャッシュを生成するものもあります。例えば
Pi
などの定数を計算する時には,ユーザはmpfr_const_pi
関数を直接呼び出せばいいですし,内部的にこのような関数が呼び出されて計算されることもあるので,定数をキャッシュしておくわけです。
もし,キャッシュしてある値より多くの精度桁数が必要となれば,自動的に再計算されます。この事態を避けるため,10%精度桁数が増えても対処できるようにしています。
MPFR関数の中には,スレッド単位のメモリプールを生成するものもあります。
このメモリプールは
mpfr_free_pool
関数で解放できます。但し,デフォルトのままMPFRビルドを行うとメモリ割り当てサイズの制限ができてしまうので,あまり大量のメモリを確保しないようにしましょう。
ユーザはいつ何時でもmpfr_free_cache
関数やmpfr_free_cache2
関数を使ってキャッシュやメモリプールを解放できます。スレッドを終了する際には必ずスレッドローカルのキャッシュを解放するようにして下さい。また,‘valgrind’ (メモリリークを防止するデバッグソフト)のようなツールを使う際には,全てのキャッシュを消去して下さい。
MPFRは,一時メモリ領域をスタック内にも確保します。このメモリ割り当て処理は,GMPビルド時の設定で指定された関数と同じものを使用します。
詳細はGNU MPマニュアルの“Custom Allocation”を参照して下さい。
つまり,メモリ処理関数を実行中に変更すると,変更後のメモリ処理関数を使ってのメモリの再割り当てや解放は行われなくなるということです。
従って,実際には,mp_set_memory_functions
関数を使ってメモリ処理関数を変更するのであれば,現在のメモリ処理関数で割り当てた全てのメモリを最初に解放しておく必要があります。独自のデータに対してはmpfr_clear
関数を,キャッシュやメモリプールはmpfr_mp_memory_cleanup
関数を,MPFRが使われる可能性のあるすべてのスレッドで実行しておきます。
mpfr_free_cache
関数を使ってもできますが,先々メモリ割り当て関数を変更する予定があるのなら,mpfr_mp_memory_cleanup
関数を使うことをお勧めします。
例えば,メモリ割り当て関数が変更される際にキャッシュが解放されないよう,浮動小数点定数をmalloc
関数で確保しておく,ということも可能です。
MPFRは間接的に使用されることもあるライブラリなので,そのようなライブラリでは,mpfr_mp_memory_cleanup
関数を呼び出して処理するメモリ解放関数を提供するようにし,ユーザにこの点周知しておいて下さい。
[注意] マルチスレッド動作のアプリケーションでは,MPFRが利用できる全てのスレッドでメモリ割り当てができるようにしなければなりません。こうしておくことで,あるスレッドで割り当てられたデータは,他のスレッドにおいても割り当てや解放ができるようになります。
フラグ,指数部の有効範囲, デフォルト精度桁数,デフォルト丸めモード,キャッシュなど,パラメータ経由でアクセスされることがないMPFRの内部データは,(スレッドセーフでないMPFRをビルドした場合には)グローバル変数であり,スレッドセーフの場合は,スレッド単位のローカル変数(スレッドローカルストレージ(Thread Local Storage),TLS) となります。 スレッド生成後のTLSの初期値は,コンパイラやスレッド実装によって決まります。 MPFRは単純に変数の初期化を行い, 実装で定義されたTLS識別子を変数に付加します。
MPFRを使ってライブラリを書くのであれば,それが利用されるアプリケーションや他のライブラリでも MPFRを使っているものとお考え下さい。つまり,指数部の有効範囲,デフォルトの精度桁数や丸めモードは自分のライブラリ以外からも変更される可能性があり,異なるスレッドで保存されていない限り,それらの値は残りません。従って,ライブラリ内で使用するこれらのMPFR内部データは,関数の処理が終わる前に保存しておく必要があります(その関数が内部データを変更するものでない限り)。 MPFRを使うソフトウェアを制作する場合は,この手の内部データの変更に非互換性が発生しないよう注意して実装を行って下さい。
Previous: Memory Handling, Up: MPFR Basics [Index]
ここでは,MPFRのパフォーマンスを生かすヒントを記しておきます。
mpfr_set
関数ではなく,mpfr_swap
関数を使って下さい。
これで仮数部のコピーを避けることができます。
a = a + b
という計算では,余計な変数は不要なので,ドーンとmpfr_add (a, a, b, ...)
と書いちゃって下さい。
Next: API Compatibility, Previous: MPFR Basics, Up: Top [Index]
MPFRの多倍長精度浮動小数点関数は,mpfr_t
型の引数を取ります。
MPFRの浮動小数点演算関数のインターフェースはGNU MPの関数とよく似た作りになっており,関数名はmpfr_
という文字列から始まります。
ユーザは変数ごとに精度桁数を指定する必要があります。計算は格納先の変数の指定精度桁数で行われますので,入力用の変数の精度桁数で計算に要するコスト が決まるわけではありません。
MPFRにおける計算の戦略について説明しましょう。まず,要求された演算を正確に(つまり「無限桁で」)実行し, しかる後に,その結果を出力先の変数の精度桁数に,指定された丸め方式で丸めて収めます。 MPFRの浮動小数点演算関数はIEEE754規格の演算の自然な拡張になっており,異なるワードサイズ,異なるコンパイラ,異なるOS環境であっても,同一の結果を返します。
MPFRには計算結果の有効精度を保証する機能はありません。つまり,ユーザ自身が,より高度なレイヤーの機能を活用するなどして(例えばMPFI(多倍長区間演算ライブラリ)等) 自分で計算結果の有効性を確認しなければなりません。 演算の結果,使用する2変数が数桁程度の有効桁数しかなく,より大きな精度桁数の変数にその結果を格納するとなれば, MPFRは馬鹿正直に格納先の桁数の精度で計算を行います。
Cの標準マクロであるerrno
の値は,エラーの有無に関わらず,MPFR関数やマクロではゼロにセットされています。本マニュアルに記述してある場合を除き,MPFRは,利用している他の関数(libc提供の関数群,メモリ割り当て関数など)と同様,errno
をセットすることはありません。
• Initialization Functions: | 初期化関数 | |
• Assignment Functions: | 代入関数 | |
• Combined Initialization and Assignment Functions: | 初期化代入関数 | |
• Conversion Functions: | 変換関数 | |
• Basic Arithmetic Functions: | 基本演算関数 | |
• Comparison Functions: | 比較関数 | |
• Special Functions: | 初等関数・特殊関数 | |
• Input and Output Functions: | 入出力関数 | |
• Formatted Output Functions: | 書式付き出力関数 | |
• Integer and Remainder Related Functions: | 整数および剰余関連関数 | |
• Rounding-Related Functions: | 丸め関係の関数 | |
• Miscellaneous Functions: | その他の関数 | |
• Exception Related Functions: | 例外とその関連の関数 | |
• Compatibility with MPF: | MPFとの互換性 | |
• Custom Interface: | カスタムインターフェース | |
• Internals: | MPFRの内部構造 |
Next: Assignment Functions, Previous: MPFR Interface, Up: MPFR Interface [Index]
mpfr_t
型の変数オブジェクトは,値を代入する前に,mpfr_init
関数やmpfr_init2
関数で初期化しておく必要があります。
変数xを初期化します。その際,精度桁数(仮数部の桁数)を正確にprecビットに設定し,値をNaNとします。
[注記] この関数とは違い,GNU MPのMPF初期化関数はゼロを代入します。
通常,変数の初期化は1回だけ行い,mpfr_clear
関数を使って消去してから再初期化するようにしましょう。
初期化後の変数に対する精度桁数の変更は,mpfr_set_prec
関数を使って行います。
精度桁数precはMPFR_PREC_MIN
以上,MPFR_PREC_MAX
以下の整数として指定します。
この指定に従わない場合の挙動は規定されていませんので注意して下さい。
va_list
で指定された全てのmpfr_t
型変数を初期化します。精度桁数はprecビットに,値はNaN が代入されます。
詳細はmpfr_init2
関数の説明を参照して下さい。
mpfr_t
型の変数,もしくはmpft_ptr
ポインタだけから構成されているva_list
が指定できます。
このva_list
は変数xから始まり,mpfr_ptr
型のNULLポインタで終わります。
変数xの仮数部が確保している記憶領域を解放します。この関数を使用する際には,該当mpfr_t
変数
への処理がすべて完了していることを確認するようにして下さい。
va_list
で指定された全てのmpfr_t
変数の記憶領域を消去します。 詳細はmpfr_clear
関数の解説を参照して下さい。
va_list
で指定された変数は全てmpfr_t
型(もしくは同等のmpfr_ptr
型)であることを想定しています。
変数リストは変数xから始まり,最後はmpfr_ptr
型のNULLポインタが来る形式で指定します。
以下,まとめて初期化する関数の使い方を示します。既に解説した通り,NULL
ポインタが変数リストの
終端に来る必要がありますが,下記の例は(mpfr_ptr) 0
と記述しています。この場合,(mpfr_ptr) NULL
と書いてもO.K.です。
{ mpfr_t x, y, z, t; mpfr_inits2 (256, x, y, z, t, (mpfr_ptr) 0); … mpfr_clears (x, y, z, t, (mpfr_ptr) 0); }
変数xを初期化し,精度桁数をデフォルト値にセットし,値としてNaN を代入します。
デフォルトの精度桁数はmpfr_set_default_prec
関数で変更できます。
[注意] プログラムの実行中,使用している他のライブラリからデフォルト精度桁数を変更され,初期化済みの変数の精度桁数は変更前のままになっているケースが見受けられます。確実に精度桁数を指定したければmpfr_init2
関数を使って下さい。
va_list
リストにあるすべてのmpfr_t
変数を初期化し,デフォルトの精度桁数をセットし,値としてNaN を代入します。
詳細はmpfr_init
関数の説明を参照して下さい。
va_list
リストの変数は全てmpfr_t
型(もしくは同等のmpfr_ptr
ポインタ)であると仮定しています。
このリストは変数xから始まり, 最後はmpfr_ptr
型のNULLポインタが終端となります。
[注意] プログラムの中で,リンクした他のライブラリからデフォルト精度桁数を変更され,元の変数の精度桁数はそのままにされるということも起こり得ます。確実に精度桁数を設定したければmpfr_inits2
関数を使用して下さい。
このマクロはnameという名前で自動的にmpfr_t
型の変数を生成し,初期化を行い,
確実に精度桁数をprecビットに設定し,値としてNaN を代入します。nameは有効な変数名でなければなりません。
このマクロは変数宣言部分で使用して下さい。mpfr_init2
関数より高速に動作しますが,次のような欠点もあります。
mpfr_clear
関数で消去してはいけません。
メモリ領域はポインタとして割り当てられており,マクロが有効なブロック(カッコ内部)を出る時に消去されます。
MPFR_USE_EXTENSION
マクロを有効化することで,このMPFR_DECL_INIT
マクロ定義部分に起因して現れる警告を抑制することができます。
デフォルトの精度桁数をprecビットに設定します。ここで
precにはMPFR_PREC_MIN
以上,
MPFR_PREC_MAX
以下の整数が指定できます。
ここで言う変数の精度桁数は,仮数部のビット長を意味します。
この関数の使用以降に呼び出されるmpfr_init
関数やmpfr_inits
関数は
設定後の精度桁数を変数にセットしますが,それ以前に初期化された変数の精度桁数は変更されません。
精度桁数の初期値は53ビットです。
[注意] MPFRを‘--enable-thread-safe’オプション設定してビルドすると,デフォルトの精度桁数は 各スレッドごとに設定されたものになります。詳細はMemory Handling を参照して下さい。
現在のMPFRのデフォルト精度桁(ビット数)を返します。詳細はmpfr_set_default_prec
関数の説明を参照して下さい。
以下,多倍長浮動小数点変数の初期化方法の例を示します。
{ mpfr_t x, y; mpfr_init (x); /* デフォルトの精度桁数で初期化 */ mpfr_init2 (y, 256); /* 精度桁数$2256ビットに設定して初期化 */ … /* プログラムが終了する間際に実行する。 */ mpfr_clear (x); mpfr_clear (y); mpfr_free_cache (); /* piのような定数のキャッシュを消去 */ }
下記の2つの関数は,計算の途中で精度桁数を変更したい場合に有用です。 例えば,Newton-Raphson法のような反復法において,解の近似度に応じて精度桁数を適宜調整する際に役立ちます。
変数xの精度桁数をprecビットに設定し直し,NaN を代入します。
変数xに入っていた値はNaN に上書きされます。この関数の機能としては,mpfr_clear(x)
で変数を消去した後に
mpfr_init2(x, prec)
で初期化した場合と同じですが,xの仮数部長が,設定後の精度桁数が十分格納できるものであれば,メモリ領域の再確保を行わない分,高速に実行できます。
精度桁数precはMPFR_PREC_MIN
以上,
MPFR_PREC_MAX
以下の任意の整数を設定できます。
変数xに格納されている値を保存しておきたい場合は,mpfr_prec_round
関数を利用して下さい。
[注意] 変数xがMPFR_DECL_INIT
マクロや,mpfr_custom_init_set
(see Custom Interface)関数で初期化されている場合は,この関数は使用できません。
変数xの精度桁数,つまり,仮数部のビット長を返します。
Next: Combined Initialization and Assignment Functions, Previous: Initialization Functions, Up: MPFR Interface [Index]
この節で解説する関数は,初期化済み(Initialization Functions 参照)の浮動小数点変数に新しい値を代入するためのものです。
これらの関数群は,opの値を,丸め方式rndで丸め,ropに代入します。 それぞれ下記のような違いがあるので,留意して下さい。
mpfr_set_ui
関数,mpfr_set_si
関数,mpfr_set_uj
関数,mpfr_set_sj
関数は,入力値が0の時,+0に変換して代入します。
mpfr_set_float128
関数は,‘--enable-float128’オプション付きで設定されたときにのみ有効な関数で,
当然,‘__float128’型が定義されているコンパイラ(GCC 4.3以降でサポート)が必要となります。
mpfr_set_float128
関数を利用したければ,mpfr.hをインクルードする前にMPFR_WANT_FLOAT128
マクロを定義しておく必要があります。
mpfr_set_z
関数,mpfr_set_q
関数,mpfr_set_f
関数では,丸め方式の指定は無効になります。
実行環境がIEEE 754標準規格をサポートしていない場合は,mpfr_set_flt
関数,mpfr_set_d
関数,mpfr_set_ld
関数,mpfr_set_decimal64
関数は,符号付きゼロを正しく扱えません。
mpfr_set_decimal64
関数は‘--enable-decimal-float’を設定してビルドし,かつ,コンパイラやシステムが‘_Decimal64’型をサポートしている場合(最近のGCCはサポートしています)のみ,利用できるようになります。このmpfr_set_decimal64
関数を使う場合は,
mpfr.hをインクルードする前にMPFR_WANT_DECIMAL_FLOATS
マクロを定義しておく必要があります。
mpfr_set_q
関数は,分子もしくは分母がmpfr_t
型で表現できない場合はエラーとなります。
mpfr_set
関数では,IEEE 754のcopy
動作に準じて,NaNの符号もそのまま渡します。但し,IEEE 754とは異なり,NaNフラグを立てます。
[注意] mpfr_t
型の浮動小数点定数を代入する際には,mpfr_set_str
関数か,他の定数関数,例えばPi
はmpfr_const_pi
関数を使うようにし,mpfr_set_flt
関数,mpfr_set_d
関数,
mpfr_set_ld
関数,mpfr_set_decimal64
関数は使用しないで下さい。
これらの関数を使うと,浮動小数点数は一旦,精度の低い浮動小数点数(53ビット倍精度や,mpfr_set_decimal64
関数の場合は10進精度)に変換されてから,MPFRに渡されてしまいます。
opに2のe乗を掛けたもの を丸め方式rndで丸めてropに代入します。 入力値が0の場合は+0に変換されます。
base進数表現として文字列sを解釈し,丸め方式rndで丸めた値をropに代入します。
有効な文字列形式の詳細についてはmpfr_strtofr
関数の説明を読んで下さい。
mpfr_strtofr
関数とは異なり,mpfr_set_str
関数は,完全に浮動小数点数として解釈できる文字列だけを扱います。
返り値の意味は,他のMPFR関数とは異なりますので注意して下さい。
最後のNULL終端まで完璧なbase進表現の浮動小数点数になっていれば0を返し,そうでない場合は,ropの値は書き換えられ,-1を返します。(返り値として三種値ternary valueが必要であれば,mpfr_strtofr
関数を使って下さい。)
[注意] ropが無限大になった時,それが無限大のsを入力したせいなのか,オーバーフローしたせいなのかを
見分けたい場合はmpfr_strtofr
関数を使って下さい。
base進表現の文字列nptrを読み取り,丸め方式rndで丸めて返します。
baseは 0 (これも下記に示すように有効な進数です)か,2以上62以下の整数でなければ
なりません。これ以外の指定をした場合の挙動は未確定です。
nptrが有効なデータ形式から始まっていれば,値はropに代入され,*endptr
は
,これがNULLポインタでなければ,有効な文字列データの終端文字を指します。
もしNULLポインタであれば,ropにはゼロが代入されます(strtod
関数の処理に準じています)。
nptrの値は,endptrがNULLポインタでなければ,これが指しているメモリ領域に格納されます
返り値は三種値(-1, 0, +1)になります。
文字列の解釈処理は,標準Cのstrtod
関数に多少の拡張を加えたものに準じます。
文字列先頭のホワイトスペースは読み飛ばされ,符号(‘+’ or ‘-’), 数字,特殊文字から成る
文字列のみ対象文字列として解釈されます。ホワイトスペースを除いた,最大限長い有効文字列が解釈の対象となります。
数値データは,小数点(なくても良い)を含む空白のない仮数部,指数部を表わす先頭文字,そして,符号を含む10進表記の空白のない指数部列(なくても良い)から成る形式でなければなりません。 仮数部の数値は10進数字(0~9)か, アルファベット(最大62文字)で表記されます。後者については, ‘A’ = 10, ‘B’ = 11, …, ‘Z’ = 35となり,36以下の進数の場合は大文字・小文字の区別はせずに扱い,37以上の進数表記の場合は, ‘a’ = 36, ‘b’ = 37, …, ‘z’ = 61となり,この場合は大文字・小文字の区別を行います。 仮数部の数値は進数未満の数でなければなりません。 小数点は,現時点におけるロケールに基づくもの(C標準仕様)か,ピリオド(ロケールとは無関係にMPFR側で規定)が使用できます。 指数部開始を示す文字は‘e’や‘E’が10以下の進数までは使用でき, ‘@’は進数に寄らず使用できます。この区切り文字以降が乗じられる進数のべき乗を表わします。 2進や16進表現の場合は,この区切り文字として‘p’や‘P’が使用できますが,この場合は,2のべき乗の意味になります。 つまり,16進表現の場合,‘1@2’と書けば256を意味しますが,‘1p2’と書くと4を意味することになるわけです。 指数部の表記は必ず10進表現でなければなりません。
引数baseが0の場合,基数は次のように自動的に決定されます。仮数部が‘0b’や‘0B’で始まる場合は基数は2となります。 仮数部が‘0x’や‘0X’で始まる場合は基数16,それ以外は全て基数は10と決定します。
[注意] 指数部の指定をするのであれば,少なくとも1桁以上の表記が必要です。 1桁以上の数値の指定がないと,指数部開始場所の文字やそれに続く符号は指数部として解釈されず,仮数部の終端扱いとなります。 同様に,‘0b’, ‘0B’, ‘0x’,‘0X’の表記のない2進表現や16進表現は,‘0’という文字で読み込みがストップしますので,00と読み込まれます。
特殊データ(無限大や非数)は‘@inf@’もしくは‘@nan@(n-char-sequence-opt)’という文字列表記となり, base <= 16であれば,‘inf’, ‘nan’, ‘nan(n-char-sequence-opt)’は大文字・小文字の区別なく認識できます。 ‘n-char-sequence-opt’は,数字,アルファベット,アンダースコア(0, 1, 2, …, 9, a, b, …, z, A, B, …, Z, _)のみ含む文字列で,空でも構いません。
[注意] NaN も含めて,符号も指定できます。 例えば,‘-@nAn@(This_Is_Not_17)’は有効な17進数のNaNを表現しています。
それぞれ,変数xにNaN (非数), 無限大,ゼロを代入します。
mpfr_set_inf
関数やmpfr_set_zero
関数は,signが非負であれば,xにプラス無限大とプラスゼロを代入します。
mpfr_set_nan
関数の場合は,符号ビットは不確定となります。
変数xと変数yが指している構造体を入れ替えます。値が丸められることはありません。
この点,3番目の引数で丸めモードを指定する3つのmpfr_set
関数グループとは挙動が異なります。
[注意] 精度桁数が入れ替わると,その後の代入処理に影響が出てくる恐れがあります。
また,仮数部のポインタも入れ替わりますので,xやyにそれを許容しない
割り当て方をした場合は,この関数を使わないようにして下さい。xや
yが,MPFR_DECL_INIT
マクロやmpfr_custom_init_set
(see Custom Interface)
で確保されたものである場合が相当します。
Next: Conversion Functions, Previous: Assignment Functions, Up: MPFR Interface [Index]
変数ropを初期化し,丸め方式rndで丸めたopを代入します。
ropの精度桁数は,mpfr_set_default_prec
関数で設定した現状のデフォルト値が設定されます。
xを初期化し,base進表現の文字列sを丸め方式rndで丸めて代入します。
詳細はmpfr_set_str
関数の説明を参照して下さい。
Next: Basic Arithmetic Functions, Previous: Combined Initialization and Assignment Functions, Up: MPFR Interface [Index]
変数opの値を丸め方式rndで丸めて,float
,double
,
long double
,_Decimal64
にそれぞれ変換します。
opがNaNの場合は, fixed NaN (qNaNもしくはシグナル)か, 0.0/0.0の結果を返します。
opが±Infの場合は,同じ符号を持つ無限大か,±1.0/0.0の結果を返します。
opがゼロの場合は,同じ符号を持つゼロを返します。
mpfr_get_float128
関数とmpfr_get_decimal64
関数は,それぞれの関数を有効化する
オプション付きでビルドされた時のみ使用できます。詳細はmpfr_set_float128
関数とmpfr_set_decimal64
関数の説明文を参照して下さい。
opの値を丸めモードrndで整数に変換し,long
型,unsigned long
型,intmax_t
型,uintmax_t
型にそれぞれ変換します。
opがNaNの時は0を返し,範囲エラー(erange)フラグを立てます。
opが変換後のデータ型としては大きすぎる場合は,オーバーフローの方向に応じて,Cデータ型として定義されている最大値,もしくは最小値を返し,範囲エラーフラグも立てます。
変換後ののデータ型に収まるようであれば,opとは異なる値が返る場合,つまり,opが整数ではない場合,不正確(inexact)フラグを立てます。
mpfr_fits_slong_p
関数, mpfr_fits_ulong_p
関数,
mpfr_fits_intmax_p
関数,mpfr_fits_uintmax_p
関数の説明も参照して下さい。
返り値としてdを返し,expには ,形式的にはexpへのポインタを代入します。ここで,expは,0.5<= abs (d) <1 ,かつ,dに2のexp乗をかけたもの が,丸めモードrnd 方向にopを丸めてdouble型(long double型)に変換したときに等しくなるように決定されます。 opがゼロの時は,同じ符号になります。符号なしゼロを扱うように実装されていれば,符号なしのままとなり, expも0が代入されます。 opがNaNもしくは無限大の時は,対応するdouble型(long double型)のNaNもしくは無限大が返され, expは不定値となります。
exp(形式的にはexpへのポインタ)とyを, 0.5<= abs (y) <1,かつ,y に2のexp乗を掛けたもの が, xをyの精度桁数にrnd方向に丸めたものと等しくなるように値を代入します。 xがゼロの時は,yにも同じ符号が付加されて, expはゼロになります。 xがNaNもしくは無限大の場合は同じ値がyに代入され,expの値は不定になります。
opの仮数部をスケールし,opの精度桁数の整数としてropに代入し,
指数部expを返り値とします。この際,現状の指数部の範囲を超えたものになる可能性があります。
つまり,opは
rop に2のexp乗を掛けたもの
と等しい値になります。
opがゼロであれば, 指数部の最小値emin
が返されます。
opがNaNもしくは無限大であれば,範囲エラーフラグがセットされ,
ropには0が入り, 指数部の最小値emin
が返されます。
返り値の指数部は,実行時におけるMPFRの最小指数部より小さい値になる可能性があります。
指数部がmpfr_exp_t
型として表現できない値になる場合は,範囲エラーフラグがセットされ,
mpfr_exp_t
型で表現できる最小値が返されます。
opを,rnd方向に丸めた後,mpz_t
型に変換します。
opがNaNもしくは無限大の時は,範囲エラーフラグを立て,
ropに0を代入し, 0を返します。それ以外の時は,ropがopと等しい時(つまり,op
が整数の時)はゼロを返し,opより大きくなる時は正の値を,opより小さくなる時は
負の値を返します。また,ropがopと異なる時,つまり,opが整数でない時は,
不正確フラグを立てます。
opを変換しmpq_t
に格納します。
opがNaN,もしくは無限大の時は,範囲エラーフラグがセットされ,
ropにはゼロが代入されます。それ以外の場合は,常に正確な変換が行われます。
opをrnd方向に丸めてmpf_t
型に変換します。
opがNaNもしくは無限大の時は,これに相当するものはMPFには存在しないので,範囲エラーフラグを立てます。
opがNaNの時はropの値は不定になります。
opが+Inf (-Inf)の時は,ropはMPF型変数の精度桁数における最大値(最小値)になります。
将来MPFが無限大をサポートするようになれば,このような動作は正しくないので,手直しされることでしょう
(ポータブルなプログラムを目指すのであれば,ropには有限の値か,無限大が代入されるようにすべきです)。
現状,MPFRの指数部はMPFと同じデータ型なので(基数は異なりますが),指数部の範囲はMPFの方がMPFRより大きくなります。
従って,オーバーフローやアンダーフローの対応付けはできません。
opを基数abs (b) の文字列として,丸めモードrndで丸めて変換します。 ここでnはゼロ(下記参照),もしくは文字列として出力される有効桁数を意味します。 後者の意味の場合は,nは2以上でなければなりません。 基数として使用できるのは2以上62以下の自然数,もしくは-2以下-36以上の整数です。これ以外の値を基数として指定すると,この関数は 何もせず即座にNULLポインタを返します。
bが2以上36以下である時,数字と小文字を使って文字列を生成します。
-2以下-36以上の場合は,数字と大文字を使います。
37以上62以下の場合は,数字,大文字,小文字がこの順に使用されます。
注意して頂きたいのは,b > 10の時で,9に続く文字は基数bによって異なります。これはGMPのmpf_get_str
関数と互換性を持たせるための仕様です。
もっとマシな動作をさせたいとお思いでしたら,シンプルなラッパー関数を実装してみて下さい。
入力値がNaNの時は,‘@NaN@’という文字列を返し, NaNフラグを立てます。入力値が+Inf (-Inf)の時は,‘@Inf@’ (‘-@Inf@’)を返します。
入力値が有限値の場合は,指数部はexpptrポインタを通じて渡されます。入力値が0の時は
現時点における最小の指数部の値が書き込まれます。有限値でさえあれば,mpfr_exp_t
型は
任意の指数部の値も格納できます。
生成される文字列は小数形式ですが,小数点は明示せず,文字列の先頭(最大桁の左側)に置かれているものと しています。例えば,-3.1416という数に対しては,"-31416"という文字列が生成され,expptrが指す先には1が格納されます。 丸めモードrndが最近接丸めで,opがちょうど出力すべき同じ指数部を持つ近似値の左右候補のど真ん中に位置している場合は, 偶数になる近似値を採用します。 基数が奇数の場合は,最小桁が偶数にできない場合があることに留意して下さい。 例えば,基数が7で有効桁数が2桁の場合,7進数(14)と(7進表現の)半分は丸められて(15)(10進数で12)になりますし 7進数で(16)と半分となり,丸められて (20)(10進数で14)になります。 同様に,7進数の(26)と半分は丸められて(26)(10進数の20)になります。
nがゼロの時は,仮数部が完全に収まるだけの桁数を確保しますので,出力された文字列をすべて再読み込みすれば, 入出力ともに最近接丸めモードの場合は,元のopと完全に同じ数を表現できます。 正確に言うと,ほとんどの場合,strの桁数は,上記の性質を満足するp = PREC(op)と bにのみ依存して決まる最小の桁数mになります。つまり, m = 1 + ceil(p*log(2)/log(b)), ということになります。ここでbが2のべき乗の場合はpはp-1に置き換えて下さい。 但し,レアケースですが,m+1桁になる場合もあります。基数が62以下の最小の事例としては, 基数が7と49で,pが186564318007の時がそれにあたります。
strがNULLポインタの時も,仮数部用の文字列メモリ領域はメモリ割り当て関数(Memory Handling
参照)
で確保され,基数が無効な値でなければ,その文字列へのポインタが返り値となります。この場合,返されたポインタが指す
文字列を解放するためには必ずmpfr_free_str
関数を使って下さい。
strがNULLポインタでない限り, ポインタが指すメモリ領域は仮数部を格納できる十分な大きさが確保されていなければなりません。どんな値に対しても安全なサイズは,nがゼロでない場合は
max(n + 2, 7)
,nがゼロの場合は,前述の説明の通りm+1確保しておく必要があります。
2バイト分余計に確保するのは,終端子用のNULL文字に加えて,マイナス符号が付加される可能性があるからです。
最低でも7バイト確保する理由は,‘-@Inf@’をNULL終端子含めて表現するためです。
基数が無効な値でない限り,文字列strへのポインタが返り値となります。
他の関数同様,変換された文字列が丸められて誤差を含む時には,不正確フラグを立てます。
mpfr_get_str
関数で割り当てられた文字列を,メモリ解放関数(Memory Handling
参照)
で解放します。
このメモリブロックはstrlen(str)+1
バイト確保されているものと想定されています。
opをrnd方向に丸めた結果が,それぞれunsigned long
型,long
型,unsigned int
型,
int
型,unsigned short
型,short
型,uintmax_t
型,
intmax_t
型といったCの基本データ型に正確に変換できる時には非ゼロを返します。
例えば,-0.5をMPFR_RNDU
モードで丸めた場合,
上記のどの関数でも非ゼロを返します。
MPFR_RNDF
モードで丸めた場合は,上記の関数と対応する変換関数(例えば,mpfr_fits_ulong_p
関数に対してはmpfr_get_ui
関数)が忠実丸めモードで対応するデータ型で表現できる数になるなら,非ゼロ値を返します。
従って,MPFR_RNDF
モードの場合は,mpfr_fits_ulong_p
関数は, ULONG_MAX
以下の非負値に対しては,非ゼロを返します。
Next: Comparison Functions, Previous: Conversion Functions, Up: MPFR Interface [Index]
op1 + op2を求めてrnd方向に丸め,ropに代入します。
符号付きゼロの場合はIEEE 754のルールが適用されます。
符号なしゼロの場合も,0は符号付きとして処理されます。つまり(+0) + 0 = (+0)や,(-0) + 0 = (-0))となります。
mpfr_add_d
関数においては,double
型は基数が2のべき乗,精度桁数はCの実装値(IEEE_DBL_MANT_DIG
マクロ定義値,なければ53ビット)として処理を行います。
op1 - op2を計算してrnd方向に丸め,ropに代入します。
IEEE 754規格のルールに従い,符号付きゼロも正しく扱います。
符号なしゼロの場合は,(+0) - 0 = (+0), (-0) - 0 = (-0),
0 - (+0) = (-0),0 - (-0) = (+0))というように扱います。
mpfr_add_d
関数に対する制限は,mpfr_d_sub
関数に対しても,
mpfr_sub_d
関数に対しても,より厳格に適用されています。
op1 ×
op2を計算し,丸めモードrndで丸めてropに格納します。
計算結果がゼロになる時の符号は,二数の符号の積で決定されます。符号なしゼロはプラス符号と判断します。
mpfr_add_d
関数と同様の制限がmpfr_mul_d
にも課されます。
opの2乗 を計算し,rnd方式で丸めてropに代入します。
op1/op2を求め,丸め方式rndで丸めてropに代入します。
演算結果がゼロの時は,二数の符号の積で符号が決定されます。
符号なしゼロの時は,プラス0として扱います。
op1が非ゼロで,op2がゼロの時,演算結果は今のところ
±
Infですが,将来的にはNaNになるかもしれません。IEEE 754で正反対の決定をしなければ,ですが。
mpfr_add_d
関数における制限事項は,mpfr_d_div
関数にも,
mpfr_div_d
関数にも適用されます。
opの平方根 を求め,rnd方式で丸めてropに代入します。 opが-0の時は,IEEE754規格の定めに従って処理します。 opが負の時は,ropにはNaNが代入されます。
opの平方根の逆数 を計算し,rnd方向に丸めてropに代入します。 opが± 0の時はropには+Infが,opが+0の時は+Infが, opが負数の時はNaNが,それぞれ代入されます。
[注意] -0に対する値は+Infで,IEEE 754-2008 規格(9.2.1節)で推奨されているrSqrt関数の値である-Infではありません。
opの立方根(k乗根)を計算し,rnd方式で丸めてropに代入します。 k = 0の場合は,ropにNaNを代入します。 kが奇数(偶数)で,opが(-Infも含む)負数である時, ropには,kのゼロではない)値に関わらず,負数(NaN)が代入されます。 opがゼロの時は,ropには通常の極限値ルールに則った符号付けがなされたゼロが代入されます。 つまり, kが奇数の時はopと同じ符号になり,偶数の時はプラス符号が付きます。
これらの関数は,IEEE 754-2008規格(9.2節)のrootn関数の処理に則った動作を行います。
この関数はmpfr_rootn_ui
関数と同じ機能を持ちます。但し,op
が-0でkが偶数の時は,+0ではなく-0を返すところが異なります。
これはmpfr_sqrt
関数と齟齬が出ないようにするための措置です。
opがゼロの時は,ropにopの値をそのまま代入します。
この関数はIEEE 754-2008規格が固まる前に作られたものなので,規格が定めたrootn関数とは動作が 多少異なります。将来のバージョンで廃止予定の関数です。
op1のop2乗
を計算し,rnd方式で丸めてropに代入します。
特殊値に対しては,ISO C99及びIEEE 754-2008規格が定めるpow
関数に準じた振る舞いをします。
pow(±0, y)
は,yが負の奇数である時,正の無限大,もしくは負の無限大を返します。
pow(±0, y)
は,yが負の偶数である時,正の無限大を返します。
pow(±0, y)
は,yが正の奇数である時,正のゼロ,もしくは負のゼロを返します。
pow(±0, y)
は,yが正の偶数である時,正のゼロを返します。
pow(-1, ±Inf)
は1を返します。
pow(+1, y)
は, NaNを含む任意のyに対して,1を返します。
pow(x, ±0)
は,NaNを含む任意のyに対して,1を返します。
pow(x, y)
は,有限の負数xと有限の非整数yに対して,NaNを返します。
pow(x, -Inf)
は,0 < abs
(x)
< 1の時は正の無限大を, abs
(x)
> 1の時は正のゼロを返します。
pow(x, +Inf)
は,0 < abs
(x)
< 1の時は正のゼロを, abs
(x)
> 1の時は正の無限大を返します。
pow(-Inf, y)
は,yが負の奇数の時,負のゼロを返します。
pow(-Inf, y)
は,yが負の偶数の時,正のゼロを返します。
pow(-Inf, y)
は,yが正の奇数の時,負の無限大を返します。
pow(-Inf, y)
は,yが正の偶数の時,正の無限大を返します。
pow(+Inf, y)
は,yが負数の時は正のゼロを,yが正数の時は正の無限大を返します。
[注記] 整数型の0は,上記の関数では+0と扱います。
この場合,pow
関数と同様,通常の極限値としては考えません。
それぞれ,-opとopの絶対値を,rnd方式で丸めてropに代入します。 ropとopが同じ変数である時には,符号を必要に応じて変更し,異なる変数であれば,rop の精度桁数がopより小さい時には丸め処理が実施されます。
このような符号処理の方式は,IEEE 754のnegate
関数とabs
関数を真似して,NaNに対しても行われます。
つまり,mpfr_neg
関数は符号を反転し,mpfr_abs
関数は符号を正にします。
但し,IEEE 754とは違って,通常NaNフラグは立てます。
op1とop2の正定値(positive difference)を計算し,rnd方式で丸めてropに代入します。 つまり,op1 > op2の場合はop1 - op2を求め, op1 <= op2の時は+0を代入し,op1もしくはop2がNaNの時はNaNを代入します。
op1に2のop2乗を掛けたもの を計算し,rnd方式で丸めてropに代入します。 ropとop1が同一の変数である場合は,2のop2乗分増えていきます。
op1を2のop2で割ったもの を求め,rnd方式で丸めてropに代入します。 ropとop1が同一の変数である場合は,2のop2乗分減っていきます。
Next: Special Functions, Previous: Basic Arithmetic Functions, Up: MPFR Interface [Index]
op1とop2を比較します。op1 > op2の時は正の値を, op1 = op2の時はゼロを,op1 < op2の時は負数を返します。 op1とop2がどちらも同じ精度桁数フルで値が入っている場合は,差を取って判断します。 どちらかの値がNaNの時は,範囲エラーフラグが立てられて,ゼロを返します。
[注記] この比較関数は3種類のケースを見分けることができます。2種類だけを見分けたい
場合は,後述するように,先読み関数(例えばmpfr_equal_p
関数は二数が等しいかどうか判断できます)を使って下さい。
比較される値にNaNがある場合は,IEEE 754規格の比較と同じ振る舞いをします。比較は浮動小数点数のみ対象なので,必要に応じて
データ変換も行われます。
op1とop2に2のe乗を掛けたもの を比較します。 返り値は上記の関数と同じです。
|op1|と|op2|を比較します。 |op1| > |op2|の時は正の値を,|op1| = |op2|の時はゼロを, |op1| < |op2|の時は負の値を返します。 比較対象の値にNaNがある場合は,範囲エラーフラグを立ててゼロを返します。
opがそれぞれNaN,無限大,NaNでも無限大でもない浮動小数点数,ゼロ,NaNでも無限大でもゼロでもない浮動小数点数である場合は,非ゼロ数を返します。それ以外の場合はゼロを返します。
op > 0の時は正の値を,op = 0の時はゼロを,
op < 0の時は負の値を返します。
引数がNaNの場合は,範囲エラーフラグを立ててゼロを返します。
mpfr_cmp_ui (op, 0)
と同じ働きをしますが,このマクロの方が高速に実行できます。
それぞれ op1 > op2, op1 >= op2, op1 < op2, op1 <= op2, op1 = op2の場合は非ゼロ数を, それ以外の場合はゼロを返します。 op1とop2の一つ以上がNaNであれば,必ずゼロを返します。
op1 < op2もしくは op1 > op2であれば非ゼロを返します。これはop1もop2も NaNではなく,op1 <> op2である場合と同等です。それ以外の場合,つまりop1 とop2にNaNがある場合,もしくはop1 = op2であれば,ゼロを返します。
op1もしくはop2がNaNであれば,つまり両者の比較ができない場合は非ゼロを返します。それ以外の場合はゼロを返します。
Next: Input and Output Functions, Previous: Comparison Functions, Up: MPFR Interface [Index]
一部の例外(mpfr_sin_cos
関数など)を除き,ここで述べている全ての関数の返り値は三種値ternary valueを返します。丸めなしの真値を返す場合は0を,真値より大きい値を返す場合は正の値を,それ以外の場合は負の値を返します。
[重要] 引数がある領域にある場合,要求精度桁数が小さくても,初等関数や特殊関数の計算(ことに,正確な丸め処理を行うため)に時間がかかることがあります。例えば三角関数やベッセル関数の引数が大きい場合がそれにあたります。
他にも,関数によっては,メモリの使用量が必ずしも出力する値の精度桁数に依存しないこともあります。mpfr_rootn_ui
関数は引数kの大きさに比例し,不完全ガンマ関数は引数opに比例してメモリ使用量が増えます。
上から順に,opの自然対数,log2(op) , log10(op) を計算し,丸め方式rndで丸めてropに代入します。 丸め方式に関わらず,opが1の時は,ropは+0になります。これはISO C99規格とIEEE 754-2008標準規格に基づいたものです。 opが± 0の時,即ち,ゼロの符号が結果に何ら影響がない場合は,ropには-Infが代入されます。
op+1の自然対数の計算を行い,丸め方式rndで丸めてropに格納します。 opが-1の時は,ropには-Infが代入されます。
この二つの関数は,それぞれopの2のべき乗 ,もしくは 10のべき乗 を計算し,丸めモードrndで丸め,ropに代入します。
exp(op)から1を引いた値 を求め,丸めモードrndで丸め,ropに代入します。
それぞれ三角関数sin(op), cos(op), tan(op)の値を求め,rnd方向に丸め, ropに代入します。
sopにはsin(op)の値を,copにはcos(op)の値を,sop, copの精度桁数に収まるよう,それぞれrnd方向に丸めて同時に代入します。sopとcopは異なる変数でなければなりません。 両方の値が丸めなしで収まる時は0を返します。より正確に言うと,返り値はs+4cという式で表現され,sopが丸めなしの場合はs=0となり, 丸めた近似値が大きくなる時はs=1,小さくなる時はs=2となります。cの値も,copの丸めた結果に応じてs同様に決まります。
sec(op), cosec(op), cot(op)の値を求め,rnd方式で丸めてropに代入します。
opの逆三角関数の値,arccos(op),arcsin(op),arctan(op)を計算し,rnd方式で丸めてropに代入します。
acos(-1)
は,与えられた丸めモードに従ってPi
に近い浮動小数点数を求めるので,必ずしもarccosの定義による
0 <=
rop < Pi
という範囲に収まるわけではありません。
求めた結果は,丸め方式によって出力範囲が決まります。
同様に,asin(-1)
, asin(1)
, atan(-Inf)
,
atan(+Inf)
,大きいopに対してatan(op)
の代入先のropの精度桁数が少ない時,等についても同様のことが言えます。
アークタンジェント2(atan2(y, x))の値を求め,rnd方式で丸めてropに格納します。
x > 0
の時はatan2(y, x) = atan(y/x)
となります。
x < 0
の時はatan2(y, x) = sign(y)*(Pi - atan(abs
(y/x)
))
となりますので,計算結果は,
-Pi
以上Pi
以下の範囲に収まります。
atan
関数同様,数学的な定義では+Pi
もしくは-Pi
となることがありますが,丸めの結果,数学的な値域に収まらないこともあり得ます。
atan2(y, 0)
は浮動小数点演算例外を発生させません。
特殊な入力値に対してはISO C99及びIEEE 754-2008規格のatan2
関数同様,次のように値が決まります。
atan2(+0, -0)
は+Pi
を返す。
atan2(-0, -0)
は-Pi
を返す。
atan2(+0, +0)
は+0を返す。
atan2(-0, +0)
は-0を返す。
atan2(+0, x)
は,x < 0の場合は+Pi
を返す。
atan2(-0, x)
は,x < 0の場合は-Pi
を返す。
atan2(+0, x)
は,x > 0の場合は+0を返す。
atan2(-0, x)
は,x > 0の場合は-0を返す。
atan2(y, 0)
は,y < 0の場合は-Pi/2
を返す。
atan2(y, 0)
は,y > 0の場合は+Pi/2
を返す。
atan2(+Inf, -Inf)
は+3*Pi/4
を返す。
atan2(-Inf, -Inf)
は-3*Pi/4
を返す。
atan2(+Inf, +Inf)
は+Pi/4
を返す。
atan2(-Inf, +Inf)
は-Pi/4
を返す。
atan2(+Inf, x)
は,有限のxの場合は+Pi/2
を返す。
atan2(-Inf, x)
は,有限のxの場合は-Pi/2
を返す。
atan2(y, -Inf)
は,有限のy > 0の場合は+Pi
を返す。
atan2(y, -Inf)
は,有限のy < 0の場合は-Pi
を返す。
atan2(y, +Inf)
は,有限のy > 0の場合は+0を返す。
atan2(y, +Inf)
は,有限のy < 0の場合は-0を返す。
双曲線関数の値,cosh(op), sinh(op),tanh(op)の値を求め,rnd方式で丸めてropに代入します。
双曲線関数sinh(op)とcosh(op)の値を同時に求め,それぞれsopとcopの精度桁数に収まるようにrnd方式で丸めて代入します。この時,sopとcopは必ずそれぞれ異なる変数を指定して下さい。
両方の出力値が丸めなしで正しい値になる場合のみ0を返します。返り値の詳細についてはmpfr_sin_cos
関数の説明を参照して下さい。
双曲線関数,sech(op),cosech(op),coth(op)の値を求め,rnd方式で丸めてropに代入します。
逆双曲線関数,arccosh(op),arcsinh(op),arctanh(op)の値をそれぞれ求めて,rnd方式で丸めてropに代入します。
opの階乗を求め,rnd方式で丸めてropに代入します。
指数積分値 を求め,rnd方式で丸めてropに代入します。 数学的な定義は,オイラー定数,opの絶対値の自然対数(log(|op|),kに関する無限和 opのk乗を,kとkの階乗の積で割ったもの の和となります。 opが正の時はEi(op)の値を返し(Abramowitz and Stegun:"Handbook of Mathematical Functions"の5.1.10式参照) ,opが負の時はE1(-op)の値(eint1(-op)とも書く)を返します(同著5.1.1式を参照)。
多重対数関数Li2(op)の値を求め,rnd方式で丸めてropに代入します。 MPFRでは -log(1-t)/tの[0, op]区間の定積分 という定義を多重対数関数として採用しています。
opのガンマ関数とopとop2の不完全ガンマ関数の値を計算し,rnd方式で丸めてropに代入します。このマニュアルではmpfr_gamma_inc
を不完全ガンマ関数(incomplete Gamma function)と呼びますが,補不完全ガンマ関数(complementary incomplete Gamma function)と呼ぶこともあります。
mpfr_gamma
関数と,op2がゼロの時のmpfr_gamma_inc
関数は,opが負の整数の時,ropにNaNを代入します。
[注記] 現状のmpfr_gamma_inc
関数は,ropやopが大きい場合は低速になってしまう問題があります。また,時によっては内部の計算でオーバーフローが発生することがあります。
opの対数ガンマ関数の値を求め,rnd方式で丸めてropに代入します。
opが1ないし2の時は,丸めモードに関わらずropは+0になります。
opが無限大,もしくは正でない整数の時は,ropは+Infになります。
このあたりの特殊な引数に対する対応は一般的なルールに従っています。
-2k-1 < op < -2kの時は,
kが非負の整数であれば,ropはNaNになります。
mpfr_lgamma
関数の解説も参照して下さい。
opのガンマ関数の値の絶対値の対数を求め,rnd方式に丸めてropに代入します。 opのガンマ関数 の値の符号は1 か -1として表現され,signpポインタが指す先に格納されています。 opが1ないし2の時は,丸めモードに関わらずropは+0になります。 opが無限大,もしくは非正の整数であれば,ropは+Infになります。 opがNaN, -Inf,負の整数のいずれかであれば,*signpの指す値は不定値となります。 opが± 0の時は,*signpの指す値はゼロの符号を意味するものになります。
opのディガンマ関数(プサイ関数とも呼ばれる)の値を求め,rnd方式で丸め,ropに代入します。 opが負の整数の場合は,ropはNaNになります。
引数が op1とop2のベータ関数の値を求め,ropに代入します。
[注記] 現時点の実装では内部でオーバーフローやアンダーフローが起きるケースについて何ら対処を行っていませんので,超高精度な値を内部で使うとトラブるかもしれません。
opのリーマン・ゼータ関数の値を求め,rnd方式で丸め,ropに代入します。
opの誤差関数および相補誤差関数の値を求め,rnd方向に丸めて,ropに代入します。
opの0, 1, n次の第1種ベッセル関数の値を求め,rnd方式で丸めてropに代入します。 opがNaN場合は,ropは常にNaNになります。opが+Infもしくは-Infの時は ropは+0になります。ropが+0でかつnが非ゼロの時は,nの偶奇や符号によってropの値は+0もしくは-0になります。
opの0, 1, n次の第2種ベッセル関数の値を求め,rnd方式で丸めてropに代入します。 opがNaNもしくは負の場合は,ropは常にNaNになります。opが+Infの時は ropは+0になります。,opがゼロの時は,nの偶奇や符号によってropの値は+Infもしくは-Infになります。
(op1 × op2) + op3や, (op1 × op2) - op3の値を求め,rnd方式で丸め,ropに代入します。特別な値(符号付きゼロ,無限大,NaN)がこの中に入っている場合,加減算の後に行う乗算の流儀に従って値が決定します。つまり,複合演算としての意味は丸め処理だけになります。
(op1 × op2) + (op3 × op4)や (op1 × op2) - (op3 × op4)の値を求め, rnd方式で丸めてropに代入します。 op1 × op2やop3 × op4の計算でオーバーフローやアンダーフローが発生した場合は,この両者を繋ぐ乗算によってropの値が決まります。
op1とop2の算術幾何平均を求め,rnd方式で丸め,ropに代入します。 算術幾何平均とは,数列u_n と v_n の共通の極限値で, u_0 =op1, v_0 =op2という初期値から出発し, u_(n+1) はu_n と v_n の算術平均, v_(n+1) はu_n と v_n の幾何平均として計算したものです。 op1,op2のどちらも負か,片方が非負である時は,ropはNaNになります。 op1,op2のどちらもゼロか,片方が有限値(無限大)の時は,ropは+0 (NaN)になります。
xとyのユークリッドノルム,即ち xとyの2乗和の平方根 を求め,rnd方式で丸めてropに代入します。 特殊値の場合はISO C99 (F.9.4.3節)および IEEE 754-2008 (9.2.1節)に述べられている通りに処理されます。 つまり, xもしくはyが無限大の時は,+Infがropに代入され,それ以外の特殊値の場合はNaNが代入されます。
アーリー関数Ai(x)の値を求め,rnd方式で丸め,ropに代入します。 xが NaNの時は, ropは常にNaNになります。xが+Infもしくは-Infの時は, ropは+0になります。 現状の実装では,引数が大きな値になることが想定されておらず, abs (x) は500より十分小さい値でないとうまく計算できません。大きな引数になる場合は 他の方法を使用するか,未来のバージョンの登場をお待ち下さい。
ropに,2の自然対数,Pi
,
オイラー定数0.577…,カタラン定数0.915…をそれぞれrnd方式で丸めて代入します。
一度これらの値がキャッシュされると,これと同じか,より低い精度桁数の値の要求があっても再計算を行いません。
キャッシュをクリアするには,mpfr_free_cache
関数かmpfr_free_cache2
関数を使って下さい。
MPFRの内部で使用される,キャッシュやプールを全て消去します。スレッドローカルのものや,全てのスレッドで共有されているものが対象となります。
明示的にmpfr_const_*
関数を呼び出していなくても,MPFRの内部で利用していることがあるので,
スレッドを停止させる前にはこの関数を呼び出すようにして下さい。
MPFRの内部で使用しているキャッシュやプールをwayのフラグ値で指定した方法で消去します。 このフラグの設定には以下のものが使えます。
MPFR_FREE_LOCAL_CACHE
フラグが立っている場合は,現在のスレッドにおけるローカルキャッシュやプールを消去
MPFR_FREE_GLOBAL_CACHE
フラグが立っている場合は,全てのスレッドから共有されているキャッシュやプールを消去
上記以外のwayに立っているフラグは現状では無視されます。将来は使用するかもしれませんので,その他のフラグは立てずにゼロにしておくようにしましょう。
[注記] mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE|MPFR_FREE_GLOBAL_CACHE)
は
今のところ,mpfr_free_cache()
と同じ働きをします。
MPFRの内部で使用されているプールを消去します。
[注記] この関数は,mpfr_free_cache
関数やmpfr_free_cache2
関数でスレッドローカルなキャッシュを消去した後には自動的に呼ばれます。
mp_set_memory_functions
関数を呼ぶ前にこの関数を呼ぶようにして下さい。詳細については
Memory Handling
をご覧下さい。
処理が成功した時はゼロを,エラーが発生した時には非ゼロを返します。
エラーが発生することは現状ない筈ですが,将来もきちんと動作させたいのであれば,返り値をチェックすることをお勧めします。
n個のtab要素の全ての和を求め,rnd方式で丸めてropに代入します。
[警告] 動作を高速化するために
tabはmpfr_t
を要素とする配列へのポインタとなっており,mpfr_t
の配列そのものではありません。
n = 0の時は+0となり,n = 1の時はmpfr_set
関数と同じ動作を行います。
誤差なしで和が求められる特殊ケースの場合のみ,
通常の加算処理(mpfr_add
関数)を無限桁で逐次行った時と同じ値を得ることができます。
特に,n >=
1で,正確な和がゼロになる場合は次のようになります。
MPFR_RNDD
方式が設定されている場合のみ,-0になります。
Next: Formatted Output Functions, Previous: Special Functions, Up: MPFR Interface [Index]
この節では,入出力ストリームを使用する入出力関数について解説します。
ここで述べる関数のstream
にNULLポインタを与えると,入力はstdin
から,出力はstdout
に行うという意味になります。
FILE *
を引数とする関数を使う時には,必ず<stdio.h>
ヘッダファイルをmpfr.hより前の位置でインクルードして下さい。mpfr.hの中でこの型を用いた関数のプロトタイプを宣言しているからです。
出力ストリームstreamに,rnd方式で丸めて得たopのbase進表現n桁の値を出力します。
基数は2以上62以下の自然数が指定できます。n桁の有効桁数は正確に出力されます。
nが0の時は,opを読み戻した時にも同じ出力結果が出せる程度に十分な桁数分出力します。
mpfr_get_str
関数の説明も参照して下さい。
有効桁だけでなく,小数点も現時点のロケールに従って最初の桁の右側に出力されます。 その後に続く指数部は,‘eNNN’という形式の10進表現となります。 基数baseが10より大きい時には,指数部の区切り文字として‘e’ではなく,‘@’が使用されます。
関数の返り値は出力した文字数で,エラー発生時にはゼロが返ります。
入力ストリームstreamからbase進表現の文字列を入力し,rnd方式で丸め, 浮動小数点型変数ropに代入します。
この関数は単語単位,つまりホワイトスペースの間の文字列を読み取り,mpfr_set_str
関数
を使って処理ます。
有効な文字列形式についてはmpfr_strtofr
関数の説明を参照して下さい。
返り値は読み取ったバイト数で,エラーが発生した場合はゼロが返ります。
opをファイルストリームstreamに,浮動小数点交換形式でエクスポートします。 特に,32ビットコンピュータとでエクスポートして,64ビットコンピュータでインポートしたり, リトルエンディアン環境でエクスポートしてビッグエンディアン環境でインポートしたりする場合に有用です。 opの精度桁数とNaNの符号もストアされます。 エクスポートが正常に行われた時のみゼロを返します。
[注記] この関数の実装は試験的なものなので,インターフェースが将来変わる可能性があります。
ファイルストリームstreamから浮動小数点交換形式(mpfr_fpif_export
関数参照)で読み取りを行い
,opにインポートします。
opの精度桁数はストリームから読み取ったもので,NaNであっても符号も常に読み取ります。
インポートされた精度桁数がゼロであったり,MPFR_PREC_MAX
を越えたものである時は,
インポートに失敗し,非ゼロを返してopには手を加えません。
他の理由でインポートに失敗した場合はopにはNaNがセットされます。また,opの精度桁数
についても,読み取りされたとしても不定になります。
インポートが正常に行われた時のみゼロを返します。
[注記] この関数の実装は試験的なものなので,インターフェースが将来変わる可能性があります。
形式は特に指定せずに,opを標準出力stdout
に改行付きで表示します。
主としてデバッグ用に使用する関数で,正常でないデータに対しても適用できます。
特に定めていない事項についてはABIを破壊しないよう,環境依存で決まります。
現状では次のような出力形式になっています。 符号ビットが立っていればNaNであってもマイナスを出力し, NaN, 無限大,ゼロに対してはそれぞれ‘@NaN@’, ‘@Inf@’,‘0’と出力します。 それ以外の値は,符号に続いて次のように出力されます。 ‘0.’に続いてpビットの2進仮数部表現(pは精度桁数),その後にゼロが続くようなら(通常のデータではあり得ないケース),大かっこを付けて出力します。大文字‘E’の後に10進表現の指数部が表示され, 不正なデータ形式や指数部範囲を超えている場合は,3つの感嘆詞(‘!!!’)を出力し,フラグに続いて, もう一度3つの感嘆詞(‘!!!’)を出力します。 フラグの意味は次の通りです。‘N’は仮数部の最大ビット(MSB)がゼロ,つまり正規化されていないことを, ‘T’は非ゼロなビットが続いていることを, ‘U’はUBF数(内部使用のみ)を, ‘<’は指数部が現状の最小指数部値より小さいことを, ‘>’は指数部が現状の最大指数部値より大きいことを,それぞれ意味します。
Next: Integer and Remainder Related Functions, Previous: Input and Output Functions, Up: MPFR Interface [Index]
mpfr_printf
関数は書式指定された出力を,標準Cのprintf
関数と同様に行うことができます。
ビルド対象のシステムでISO Cの可変長引数の関数と,可変長引数にアクセスするためのマクロがサポートされている場合のみ,
この関数が使用できます。
この関数を使う際には,mpfr.h
の前に,必ず<stdio.h>
をインクルードしておく必要があります。
mpfr.hにおけるこの関数のプロトタイプ宣言で使用しているからです。
mpfr_printf
関数で指定できる書式指定は,printf
関数の書式指定を拡張したものになっています。書式指定の形式は次のようになっています。
% [フラグ] [文字数] [.[精度桁数]] [データ型] [丸め方式] 変換形式
‘フラグ(flag)’, ‘文字数(width)’, ‘精度桁数(precision)’はprintf
関数と同じ意味を持ちます。‘精度桁数(precision)’は変換形式で指定した基数(base)に基づいて表示される桁数となります。しかし,例えば‘Re’という書式指定を行うと,デフォルトの表示精度桁数は,‘e’という書式指定で設定した場合とは違ったものが設定されます。
mpfr_printf
関数はGMPが提供するデータ型に対する書式指定と同じものが利用できます。但し,廃止予定の書式指定である‘q’ではなく,‘ll’と指定して下さい。
‘h’ short
‘hh’ char
‘j’ intmax_t
またはuintmax_t
‘l’ long
またはwchar_t
‘ll’ long long
‘L’ long double
‘t’ ptrdiff_t
‘z’ size_t
上記は標準データ型にする書式指定で,これ加えて,GMPが定義する‘データ型(type)’と,MPFRのデータ型に対する‘R’指定と‘P’指定が利用できます。下記の表の2列目が,‘データ型(type)’に続く,‘変換形式(conv)’の書式指定となります。
‘F’ mpf_t
, 浮動小数点形式‘Q’ mpq_t
, 整数形式‘M’ mp_limb_t
, 整数形式‘N’ mp_limb_t
配列, 整数形式‘Z’ mpz_t
, 整数形式‘P’ mpfr_prec_t
, 整数形式‘R’ mpfr_t
, 浮動小数点形式
‘データ型(type)’の指定は,GMPのマニュアルに記してある制限をそのまま受け継ぎます。
詳細はGNU MPの“書式指定形式”を参照。
特に,‘データ型(type)’指定は(‘R’と‘P’を除き),GMPビルド時にgmp_printf
関数が有効になっていないと使用できません。当然,‘t’のような標準のデータ型指定も,使用する環境でCライブラリがサポートしていないと使用できません。
‘丸め方式(rounding)’フィールドはmpfr_t
型の場合のみ指定でき,他のデータ型に対しては使用しないで下さい。
‘P’指定や‘R’指定がない場合は,mpfr_printf
関数はgmp_printf
関数と同じ書式で出力します。
‘P’指定は,その次に‘d’, ‘i’,
‘o’, ‘u’, ‘x’, ‘X’が続き,mpfr_prec_t
型の値に対して適用されます。
この指定が必要になる理由は,mpfr_prec_t
型が,必ずしもint
型などの固定サイズの標準データ型であるとは限らないからです。
‘精度桁数(precision)’フィールドは表示される最小の桁数の指定で,デフォルトは1です。
プログラム例:
mpfr_t x; mpfr_prec_t p; mpfr_init (x); … p = mpfr_get_prec (x); mpfr_printf ("%Puビットの変数x", p);
‘R’指定の後は‘a’, ‘A’, ‘b’,
‘e’, ‘E’, ‘f’, ‘F’, ‘g’, ‘G’, ‘n’が続き,mpfr_t
型データの出力指定が行われます。
‘R’指定の後に‘丸め方式(rounding)’の指定も,下の表のように可能となります。
‘U’ 正の無限大方向の丸め ‘D’ 負の無限大方向の丸め ‘Y’ ゼロから遠ざかる方向の丸め(切り上げ) ‘Z’ ゼロ方向への丸め(切り捨て) ‘N’ 最近接値への丸め(なるべく偶数になるように) ‘*’ mpfr_t
型データの前にあるmpfr_rnd_t
指定の方式による丸め
デフォルトの丸めモードは最近接値(‘N’)です。 下記の例では同じ出力形式になる3種類の書式指定を使っています。
mpfr_t x; mpfr_init (x); … mpfr_printf ("%.128Rf", x); mpfr_printf ("%.128RNf", x); mpfr_printf ("%.128R*f", MPFR_RNDN, x);
ゼロから遠ざかる方向の丸めが‘Y’で指定されるのは,ISO C規格で,‘A’が16進出力の指定として予約されているからです(下記の表参照)。
‘変換書式(conv)’はmpfr_t
用の書式指定と共に,下記のようなものが使用できます。
‘a’ ‘A’ 16進浮動小数点表示, C99形式 ‘b’ 2進出力 ‘e’ ‘E’ 指数形式の浮動小数点表示 ‘f’ ‘F’ 固定小数点形式 ‘g’ ‘G’ 固定小数点形式,または 指数形式表示
‘b’という書式変換指定を使うと,対象のmpfr_t
型データを2進表現します。他のデータ型には使用しないで下さい。
それ以外の書式変換指定は,double
型に対する指定と同じ意味です。
10進以外の出力の場合,仮数部は指定された基数の進数表現となりますが,指数部は常に10進表現となります。
非数や無限大は常に特定の文字列で出力されます。‘a’, ‘b’, ‘e’, ‘f’, ‘g’の場合はnan
, -inf
, inf
と出力され,‘A’, ‘E’, ‘F’, ‘G’の場合はNAN
, -INF
, INF
と出力されます。
‘精度桁数(precision)’フィールドに指定がある場合,mpfr_t
型の値は,指定丸め方式で,指定精度桁数になるように丸められます。
精度桁数指定がゼロで,最近接値への丸めが指定されおり,‘変換書式(conv)’の指定が‘a’, ‘A’, ‘b’, ‘e’,
‘E’, のどれかである場合,丸めた結果が同じ指数部の値で,二つの値のちょうど中間にあるなら偶数になる方に丸め,それ以外の場合は,ゼロから遠ざかる方向の値に丸められます。
例えば"%.0RNe"
という書式指定に対しては,85は"8e+1"と出力され,95は"1e+2"と出力されます。この方式は,‘g’ (‘G’の場合も同様) 指定の時,‘e’ (‘E’も同様)形式で出力される際にも適用されます。
精度桁数をint
型の最大値より大きい値に指定した場合は,特に警告も出さず,INT_MAX
の値を精度桁数として使用します。
‘精度桁数(precision)’フィールドが空で,‘変換書式(conv)’に‘e’や‘E’を指定した場合(例えば%Re
や%.RE
という指定) の場合は,出力値を正確に読み戻すことができる桁数で出力されます。つまり,入力値と出力値が同じ精度,かつ,どちらも最近接値へ丸められているものとして扱います。これはmpfr_get_str
関数に対する場合と同様です。
‘f’, ‘F’, ‘g’, ‘G’が変換書式に指定されている時,‘精度桁数(precision)’フィールドが空の時のデフォルトの精度桁数は6です。
下記の関数に対して,int
型の最大値INT_MAX
を超えるパラメータの設定がされている場合は,何も出力しません(出力先がstdout
でもbufでもstrであっても同じです)。
この場合,関数は-1を返し,範囲エラーフラグを立て,POSIX環境などEOVERFLOW
マクロが定義されていればerrno
に EOVERFLOW
を代入します。注意してほしいのは,
これ以外のエラー発生時(今のところ,メモリ解放関数で起こり得る)にも,内部ライブラリ呼び出しの結果, errno
の値は変化してしまう可能性があるということです。
出力先streamに対して,書式指定文字列templateに従った出力を行います。 返り値は出力した文字数で,エラー発生時は負数が返されます。
標準出力stdoutに対して,書式指定文字列templateに従った出力を行います。 返り値は出力した文字数で,エラー発生時は負数が返されます。
NULL終端子を持つ文字列を,書式指定文字列templateに従って生成し, bufに格納します。bufと他の引数はメモリ内で重複してはいけません。 返り値はNULL終端子を除いてbufに書き込まれた文字数で,エラーが発生した場合は負数が返されます。
NULL終端子を持つ文字列を,書式指定文字列templateに従って生成し, bufに格納します。nがゼロの時は何も書き込まず,bufはNULLポインタとなります。nに正数が指定される場合は,最初のn-1文字がbufに書き込まれ,n番目の文字がNULLになります。 nが十分大きい場合は,最後のNULL文字を除き,書き込まれた文字数が返り値となり,エラーが発生した場合は負数が返り値となります。
現在のメモリ割り当て関数(Memory Handling
参照)を使って確保したメモリブロックに,NULL終端子を持つ文字列を書き込みます。メモリブロックへのポインタはstrに与えます。メモリブロックを解放するときには必ずmpfr_free_str
を使って下さい。
返り値はNULL終端子を除いて書き込まれた文字数で,エラーが発生した場合は負数が返され,strの値は不定となります。
Next: Rounding-Related Functions, Previous: Formatted Output Functions, Up: MPFR Interface [Index]
opを丸めて整数にしてropに代入します。
mpfr_rint
関数は,rnd方式を用いて最も近い整数に丸めます。他の5つの関数も,丸め方式を固定して整数に丸めます。
mpfr_ceil
関数: op以上となる隣接整数に丸める
(mpfr_rint
関数でMPFR_RNDU
を指定した時と同等)
mpfr_floor
関数: op以下となる隣接整数に丸める
(mpfr_rint
関数でMPFR_RNDD
を指定した時と同等)
mpfr_round
関数: opをゼロから遠ざかる方向に丸めて,最も近い整数に
(IEEE 754-2008規格のroundTiesToAwayモードに相当)
mpfr_roundeven
関数: opに偶数丸めを行って,最も近い整数に
(mpfr_rint
関数でMPFR_RNDN
を指定した時と同等)
mpfr_trunc
関数: opをゼロ方向に丸めて,最も近い整数に
(mpfr_rint
関数でMPFR_RNDZ
を指定した時と同等)
opがゼロ,もしくは無限大の時には,同符号の同じ値をropに代入します。
返り値については,丸め誤差なしで正確に変換できた時はゼロ, opより大きくなる場合は正数, opより小さくなる場合は負数となります。 正確に言うと,opが正確に整数としてropに代入できればゼロ, opが,整数ではあるが,ropでは正確に表現できない場合は1もしくは-1, opが整数でない時には,2ないし-2を返します。
opがNaNの時は,NaNフラグが立ちます。他の例外処理も同様で,
ropに代入される値がopとは異なる場合は,ISO C99のrint
関数の処理方法に則って,不正確フラグを立てます。
よりIEEE 754 や ISO TS 18661-1に従った振る舞いをしたい時,つまり,これらの整数化関数を数学関数として扱いたい時には,
mpfr_rint_*
関数を使った方がいいでしょう。
これらの関数では2重に丸めが発生することはありません。
例えば10.5 (2進では1010.1)を最近接丸めでmpfr_rint
関数を使うと12 (2進1100)という2ビット整数
になります。この場合,2つの候補となる2ビット整数8と12がありますが,最も近いのは12だからです。
2重丸めを行ったとすると,最初に偶数丸めを行って10となり,次にまた偶数丸めを行って8となります。
opを丸めて整数化してropに代入します。
mpfr_rint_ceil
関数: op以上の整数に丸める
mpfr_rint_floor
関数: op以下の整数に丸める
mpfr_rint_round
関数: ゼロから遠ざかる方式で最も近い整数に丸める
mpfr_rint_roundeven
関数: 偶数丸め方式で最も近い整数に丸める
mpfr_rint_trunc
関数: ゼロ方向へ丸めて整数に
素直に整数化できない時にはrnd方式で丸めます。 opがゼロもしくは無限大の時にはropには符号も含めて同じ値を代入します。 返り値は三種値で,他の数学関数同様に扱われ,整数化関数(round-to-integer funcion)と同じものになります。
mpfr_rint
関数とは対照的に,これらの関数は2重に丸めを行います。
最初にopを関数ごとに指定された方向に丸めて最近接の整数に丸め,
この整数がropで正確に表現できない時には,rndで指定した丸め方式でもう一度
丸めを行います。従って,これらの整数化関数(round-to-integer
function)はより数学関数らしく振舞います。つまり,返される結果は,実数に対して正確に整数化
したものを,正しく丸めたものになる訳です。
例えば,mpfr_rint_round
関数に,最近接丸めと2ビットの精度桁指定を行ったとすると,
6.5は7となり (ゼロから遠ざかる丸め), 7は最近偶数丸めの結果,8になります。6も2ビット整数
表現でき,8よりも6.5に近いのですが。
opの小数部をrnd方向に丸めて取り出し,符号も等しくなるようにropに代入します。
mpfr_rint
関数と同様に,
rndは正確な小数部を丸める時にのみ影響し,小数部の取り出しには影響を与えません。
opが整数,もしくは無限大の時はropにはopと同符号のゼロを代入します。
opの整数部をiopに,小数部をfopに同時に代入します。
それぞれrnd方向に丸めてiopとfopの精度桁数に納めます。
これはmpfr_trunc(iop, op, rnd)
と
mpfr_frac(fop, op, rnd)
)と同じ処理になります。変数iopと
fopは異なる変数でなければなりません。どちらも正確な値を返すことができた時のみゼロを返します。
mpfr_sin_cos
関数の返り値についての記述も参照して下さい。
x - nyの値を計算し,rnd方式で丸めてrに代入します。
ここでnは,xをyで割った時の整数の商で,次のように定義されます。
nはmpfr_fmod
関数とmpfr_fmodquo
関数を用いてゼロ方向に丸められ,
mpfr_remainder
関数と
mpfr_remquo
関数に対しては偶数丸めで最近接の整数になります。
特殊値については,ISO C99規格のF.9.7.1節に述べられているように扱います。 xが無限大,もしくはyがゼロの時は,rはNaNになります。 yが無限大でxが有限値の時は,rはxをrの精度桁数に丸められた値になります。 rがゼロの時は,xと同符号になります。 返り値はrに応じた三種値になります。
加えて,mpfr_fmodquo
関数とmpfr_remquo
関数は
*qにおける商nの低位のビットを,xをyで割った時の符号と共に格納します。
正確に言うと,long
型のビット数から1少ないビット数分ということになります。
但し,全てのビットがゼロの時は除きます。この時はゼロを返します。
xは,正しい商が実用的なものではないyに比して絶対値が大きくなる可能性があります。
mpfr_remainder
関数とmpfr_remquo
関数は引数のリダクション用に使用されています。
opが整数の時のみ,ゼロ以外の数を返します。
Next: Miscellaneous Functions, Previous: Integer and Remainder Related Functions, Up: MPFR Interface [Index]
デフォルトの丸めモードをrndに設定します。 初期設定では最近偶数丸めがデフォルトです。
現在のデフォルトの丸めモードが返されます。
xをrnd方式で丸め,精度桁数precに納めます。精度桁数はMPFR_PREC_MIN
以上,MPFR_PREC_MAX
以下
でなければなりません。そうでない時の動作は定義されていません。
precがxの精度桁数以上であれば,新たに仮数部を格納するために必要なメモリ領域を確保し,下の桁にはゼロが詰め込まれます。
precがxの精度桁数未満であれば,指定された丸めモードで仮数部はprec桁に丸められます。
どちらの場合でも,xの精度桁数はprecに置き換えられます。
ここで,mpfr_prec_round
関数を使って,aの逆数を求めるニュートン法を実装した例を示します。
xは既に頭からnビット正しい近似値であると仮定しています。
mpfr_set_prec (t, 2 * n); mpfr_set (t, a, MPFR_RNDN); /* aを2nビットに丸める */ mpfr_mul (t, t, x, MPFR_RNDN); /* tは2nビットに正確に丸められる */ mpfr_ui_sub (t, 1, t, MPFR_RNDN); /* 大きい方のnビット分桁落ち */ mpfr_prec_round (t, n, MPFR_RNDN); /* tはnビットに正確に丸められる */ mpfr_mul (t, t, x, MPFR_RNDN); /* tはnビットに正確に丸められる */ mpfr_prec_round (x, 2 * n, MPFR_RNDN); /* 丸めなしで2nビットに */ mpfr_add (x, x, t, MPFR_RNDN); /* xは正確に2nビットに丸められる */
[警告] この関数で使用するxはMPFR_DECL_INIT
マクロや,mpfr_custom_init_set
関数
(see Custom Interface)で絶対に初期化しないで下さい。
bを未知数xをrnd1方向に丸め,2の E(b)-err乗の誤差を持つ近似値と仮定します。ここでE(b)はbの指数部を意味します。この時,指数部の範囲制限はないものとして, xを正しくrnd2方向に丸めてprec桁にできるのであれば,この関数は非ゼロを返します。 それ以外の場合は,NaNや無限大の場合も含めて0を返します。 言い換えると,bの誤差が2の k乗 ulp以下で抑えられ,bがprec桁の精度を持っているならば, err=prec-kという評価式を得られるということです。 この関数は,引数を変更しません。
rnd1がMPFR_RNDN
もしくはMPFR_RNDF
である時には,
誤差は正もしくは負になると想定されますので,誤差範囲はrnd1が行う丸めの2倍,つまり
errと同じ値になります。
rnd2がMPFR_RNDF
の時,
rnd3にはrnd1とは反対方向の丸め方式を設定するものとします。
rnd1がMPFR_RNDN
もしくはMPFR_RNDF
の時は,rnd3にはMPFR_RNDN
を設定します。
さすれば,mpfr_can_round (b, err, rnd1, MPFR_RNDF, prec)
の返り値は,
mpfr_set (y, b, rnd3)
をprec桁のyで呼び出した後に,
yがxの忠実丸め結果と等しくなると保証できる時のみ,非ゼロを返します。
[注記] この関数については,返り値が三種値ternary valueのどれになるかは一般的には
決められません。しかし,真値が正しくprec桁で表現できないと分かっているのであれば,
下記のような方法を使って, 非ゼロな三種値のどちらになるのか,丸め方式
rnd2に関係なく決めることができます。以下の例ではMPFR_RNDZ
はいずれの方向付き丸めに置き換え可能です。
if (mpfr_can_round (b, err, MPFR_RNDN, MPFR_RNDZ, prec + (rnd2 == MPFR_RNDN))) { /* 'b'を,丸め方式'rnd2'で丸めて'prec'ビットにしたものを'r'に代入し 返り値の三種値を'inex'に格納する */ inex = mpfr_set (r, b, rnd2); }
実際,rnd2がMPFR_RNDN
であれば,方向付き丸めでprec+1ビットに丸められるかどうかを
確認できます。
これができるなら,最近接丸めで確実にprec ビットになりますし,加えて,
非ゼロ三種値のどれになるかも正しく決められます。
ただし,bが
prec ビットで表現できる数に近接しているときはその限りではありません。
この関数についての詳細な事例はexamplesサブディレクトリにあるcan_round.cを参照して下さい。
xの仮数部を格納するために必要となる最小のビット数を返します。 xがゼロや非数など特別な数の場合は,0を返します。
丸め方式rndに対して,その丸めモードを表わす文字列("MPFR_RNDD", "MPFR_RNDU", "MPFR_RNDN", "MPFR_RNDZ","MPFR_RNDA")を返します。rndが丸めモードとして不適切な値の時は,NULLポインタを返します。
1ないし複数の引数op(データ型はmpfr_t
, long
, double
など)を取る関数fooを与え,
ropにfoo(op,...)
の結果を,最近接値から離れる丸め(round-nearest-away)方式で丸めた値を代入します。
この丸め方式は,同じ値になる場合を除いて,偶数最近接値への丸めと同じ手法で定義されており,
ゼロから離れる方向の値を返します。
関数fooは入力値で, 次の引数から最後から2番目の引数については,rop以降の引数が,丸めモードの指定が最後となるように
与えられ,これらが最初の引数である関数の引数としてfoo(op,...)
に渡されて実行され,丸めモード指定に従って値が丸められます。返り値は三種値になります。但し,処理が正しくできたと期待できる時のみで,期待できない時には
mpfr_round_nearest_away
マクロはうまく働かないでしょう。
実装上の制約により,このマクロは,最小指数部値emin
に到達してしまう可能性のある時には使用しないで下さい。
また,このマクロは,コンパイラがfooのプロトタイプ宣言と,引数リストopの不整合を検出できるようになっています。
C99コンパイラでのみ,opの多重指定が可能になっており,C99コンパイラでは一つだけを受け付けます。
[注記] このマクロは試験的な実装になっており,インターフェースは将来変更される可能性があります。
unsigned long ul; mpfr_t f, r; /* r, f, ulを初期化して値をセットする。必要があればeminも設定 */ int i = mpfr_round_nearest_away (mpfr_add_ui, r, f, ul);
Next: Exception Related Functions, Previous: Rounding-Related Functions, Up: MPFR Interface [Index]
xとyのどちらかがNaNであれば,xにはNaNが代入され, 他の場合と同様,NaN フラグも立ちます。 xとyが等しい時はxは変更されません。 それ以外の場合は,xがyと異なる場合は,xは ,xの精度桁数と現状の指数部の範囲で,y方向に隣の浮動小数点数が代入されます。 無限大の場合は,最小あるいは最大の浮動小数点数として機能します。 結果がゼロの時は,符号は同じものが保持されます。 アンダーフロー,オーバーフロー,不正確例外が発生することはありません。
yが正の無限大(負の無限大)の時のmpfr_nexttoward
関数と同じ処理を行います。
ropにop1とop2の最小値(最大値)を代入します。op1と op2が共にNaNの時は,ropにもNaNが代入されます。op1と op2のどちらかがNaNの時は,ropには有限数値の方が代入されます。 op1とop2が互いに符号の異なるゼロの時は,ropには -0 (+0)が代入されます。
0 <= rop < 1区間の一様乱数を浮動小数点数として与えます。 正確に言うと,この乱数は正規化されていない仮数部と指数部がゼロの浮動小数点数として表現されます。 当然,最終的には正規化されて指数部がeとなりますから,仮数部の最後のeビットは常にゼロとなります。
指数部が現状の指数部範囲に収まっていれば0を返し,指数部範囲を超えていればropにはNaN
を代入し,非ゼロを返します。とはいえ指数部範囲を超えるということは普通は起こりません。
2番目の引数は,gmp_randstate_t
構造体で,GMPのgmp_randinit
関数を使って
生成しておいて下さい(GMPマニュアル参照)。
[注記] MPFRでは,ropに代入される値や,以降の乱数を制御するstateの新しい値 は,マシンのワードサイズには依存せずに決まります。
一様分布に従う浮動小数点数を生成します。 浮動小数点数ropは,[0, 1]区間の連続一様分布に従う実数乱数がrnd方向に丸められた 値と見ることができます。
2番目の引数であるgmp_randstate_t
構造体はGMPのgmp_randinit
関数で生成したものを
指定して下さい(GMPマニュアル参照)。
[注記] mpfr_urandomb
の注記はこの関数でも有効です。さらに言うと,
丸められる前の正しい乱数値と次の乱数状態は,現状の指数部範囲と丸めモードはに依存しませんが,
代入される変数の精度桁数には依存します。つまり,乱数生成器の状態が同じものから出発したとしても,
代入される変数の精度桁数が変更されると,その値や乱数生成器の状態は完全に違ったものに変化します。
平均0,分散が1のガウス分布に従う乱数を一つ(mpfr_grandom
では最大2つ)生成し,
浮動小数点数として与えます。
mpfr_grandom
関数は,rop2がNULLポインタの場合は,
乱数を一つだけ生成してrop1に代入します。
浮動小数点数rop1 (とrop2)は,標準正規ガウス分布に従った実数乱数を rnd方向に丸めたものと解釈できます。
gmp_randstate_t
引数はGMPのgmp_randinit
関数で生成したものを指定して下さい。(GMPマニュアル参照)。
mpfr_grandom
関数の返り値は三種値で,その組み合わせは
mpfr_sin_cos
関数と同じです。rop2がNULLポインタであれば,2番目の三種値は
ゼロになります。三種値を一つだけ返すということは,結果を一つだけ返す関数の三種値とは異なるものになる,ということに留意して下さい。それ以外の時は,三種値のうち非ゼロの値が返ってきます。
[注記] mpfr_urandomb
関数の注記はここでも有効です。加えて,指数部の範囲と
丸めモードは次の乱数生成器の状態に影響を与える可能性があります。
[注記] mpfr_nrandom
関数は,精度桁数が大きくなるとmpfr_grandom
関数よりずっと
高速に動作します。従って,mpfr_grandom
関数は廃止予定で,将来消去される予定です。
平均が1の指数分布に従う乱数を浮動小数点数として与えます。
その他の性質はmpfr_nrandom
関数と同じです。
xは通常の非ゼロな浮動小数点数で,仮数部は[1/2,1)に存在しているという前提で,xの指数部を返します。 この関数では xが現状の指数部範囲を超えていても正しく処理を行います。 xがNaN, 無限大,ゼロの時の処理は定めていません。
xが通常の非ゼロの浮動小数点数である時,xの指数部にeを代入します。 eが現状の指数部範囲に収まっていればゼロを返し,それ以外の時は, 非ゼロを返し,xは変更しません。
opの符号部がセット,つまり負数や,-0, 符号部の設定されたNaNの時のみ非ゼロを返します。
opを丸め方式rndで丸め,ropに代入し,しかる後にsの値が非ゼロ(ゼロ)の時は,符号も代入(クリア)します。 これはopがNaNの場合も同様に処理されます。
op1を丸め方式rndで丸めてropに代入し,その符号ビットをop2に代入します。
op1やop2がNaNであっても同様に処理されます。この関数は
mpfr_setsign (rop, op1, mpfr_signbit (op2), rnd)
と同じ働きを行います。
NULL終端子付きの文字列としてMPFRのバージョンを返します。
MPFR_VERSION
は定数として与えられるMPFRのバージョン番号です。
MPFR_VERSION_MAJOR
, MPFR_VERSION_MINOR
,
MPFR_VERSION_PATCHLEVEL
はそれぞれ,MPFRのメジャー番号,マイナー番号,パッチレベルを表わす定数です。
MPFR_VERSION_STRING
は,文字列定数として与えられるバージョン定数で,開発バージョンやプレリリース用のバージョンに使用されるサフィックスも含まれています。この文字列定数はmpfr_get_version
と比較でき,ヘッダファイルやライブラリをチェックする際に役立ちます。
if (strcmp (mpfr_get_version (), MPFR_VERSION_STRING)) fprintf (stderr, "警告: ヘッダファイルとライブラリのバージョンが一致していません。\n");
[注記] 上記のように比較して文字列が一致しなくてもエラーとは言えません。 古いMPFRバージョン用に作ったプログラムは,ライブラリのバージョン管理システムが許可していれば, 新しいバージョンのMPFRと動的リンクすることもできます。
major, minor,patchlevelから,MPFR_VERSION
と同じ形式の整数値を
生成します。
下記は,コンパイル時にMPFRのバージョンをチェックするプログラム例です。
#if (!defined(MPFR_VERSION) || (MPFR_VERSION<MPFR_VERSION_NUM(3,0,0))) # error "MPFRのバージョンが正しくありません。" #endif
MPFRライブラリに適用されたパッチ(内容はPATCHESファイルに書いてあります)のidを含む,NULL終端子文字列を返します。 文字列はスペースで区切られています。
[注記] 古いMPFRとコンパイルしたプログラムを新しいMPFRと動的リンクするのであれば, コンパイル時の古いMPFRの識別子は無効になります。 まぁ大して重要な情報ではありませんので。
MPFRがスレッドセーフになるよう,スレッドローカルなストレージを有効にしてコンパイルされた時には
(‘--enable-thread-safe’オプションつきで設定します。INSTALL
ファイルを参照のこと),非ゼロを返します。
スレッドセーフでない時にはゼロを返します。
MPFRが‘__float128’をサポートしている時には非ゼロを返します。 つまり,MPFRが‘--enable-float128’オプション付きで設定するとそうなります。 サポートしていない時はゼロを返します。
MPFRを‘--enable-decimal-float’オプション付きで設定するとMPFRは10進浮動小数点数をサポートしますが, この時にはこの関数は非ゼロを返します。 サポートしていない時はゼロを返します。
MPFRが‘--with-gmp-build’オプション,もしくは ‘--enable-gmp-internals’オプション付きでビルドされていると,MPFRはGMPの内部関数を 利用します。この時この関数は非ゼロを返します。そうでない時にはゼロを返します。
MPFRが全てのスレッドでmpfr_const_pi
や
mpfr_const_log2
などのMPFR定数を保持するキャッシュを共有するようにコンパイルされていると(‘--enable-shared-cache’オプション付きでビルドした場合),非ゼロを返します。 キャッシュ共有ができない場合はゼロを返します。
この関数が非ゼロを返す時には,MPFRを使用するアプリケーションは,‘-pthread’オプションを付けてコンパイルする必要があります。
コンパイル時に使用した閾値ファイルを文字列で返します。 このファイルは通常,プロセッサの種類ごとに決まっています。
Next: Compatibility with MPF, Previous: Miscellaneous Functions, Up: MPFR Interface [Index]
関数実行時点における,MPFR浮動小数点型の指数部の最小値と最大値をそれぞれ返します。 浮動小数点型の正の最小値は1/2に2の指数部最小値乗を掛けたもの ,正の最大値は(1 - epsilon) に2の指数部最大値乗を掛けたもの です。 ここで,epsilon は浮動小数点型の精度桁数によって決まる定数です。
浮動小数点型の指数部の最小値と最大値をそれぞれ設定します。 expを,実行環境に依存して決まる指数部の範囲内で最小値,あるいは最大値として設定できない場合は非ゼロ数を返します。この場合は,現状の指数部最小値ないし指数部最大値は変化しません。指数部の最小値・最大値を設定できれば,ゼロを返します。
これらの関数の実行後は,ユーザの責任で入力される浮動小数点数が,mpfr_check_range
関数を使用するなどして,この新しい指数部の範囲内に収まっていることをチェックする義務が生じます。
この範囲からはみ出している値が入力された時のデフォルトの動作は,ISO C規格でも決まっていません。mpfr_check_range
関数にあるように,その際の挙動については明文化されています。
[注記] 定数値のキャッシュは,これらの関数で指数部の範囲が変更された後もそのままです。 これは,API経由でキャッシュ値を直接ユーザが使うことができない,ということではありません。 MPFRは,内部的には必要に応じて指数部の範囲を超えることを許容しています。
emin
> emax
かつ,浮動小数点値を出力しなければならない場合は,
その挙動は不定です。mpfr_set_emin
関数も
mpfr_set_emax
関数もこの条件はスルーしますし,いつでも起こり得る事象ではあります。
mpfr_set_emin
関数やmpfr_set_emax
関数で設定できる指数部の最小値と最大値をそれぞれ返します。
これらの値は事項環境に依存しますので,
mpfr_set_emax(mpfr_get_emax_max())
や
mpfr_set_emin(mpfr_get_emin_min())
といったことを行うと,ポータビリティを損ねます。
この関数は,xがyをrnd方式で,指数部の範囲も拡張して正しく丸めた値になっており,
tには三種値(ternary value)が入っていることを仮定しています。
例えば,t = mpfr_log (x, u, rnd)
で,yはuの自然対数の正しい値が入っているものとします。
さすれば,tは,xがyより小さい時には負数,
xがyより大きければ正数,xとyが等しければゼロになります。
この関数は,xが現状受け入れ可能な値の範囲に入っていれば,値を入れなおします
xの指数部が現状の許容範囲から外れていれば,オーバーフローもしくはアンダーフローが発生します。
tの値は2重に丸めが発生することを防止するために使用されます。
新しいxの値が真値であるyと等しい時にはゼロを,
yより大きくなる場合は正数を,
yより小さくなる場合は負数を返します。
他の関数とは違い,
新しいxの値は(未知の)真値であるyと比較し,
入力時のxとは比較しません。つまり,三種値は伝達されます。
[注記] xが無限大で,tが非ゼロである時(つまり,丸めた結果,不正確な無限大になった時)
オーバーフラグが立てられます。
これが役に立つのは,mpfr_check_range
関数が,MPFRの関数内で呼ばれ,内部処理でフラグがセット
される場合です。
この関数は,非正規数演算(subnormal)をエミュレートしつつ,xを丸めます。xが非正規化エリアの外にある場合は,
三種値ternary value tだけを伝えます。
xが非正規エリアに入っている時には,
丸めモードrndと,引数の三種値tに従って,二重に丸めを行わないようにしつつ,xをEXP(x)-emin+1
精度桁数に丸めます。正確に言うと,非正規化エリアの中では,e
は
emin
の値になり,xは丸められて固定小数点演算用として2の
e-1乗
を掛けられて整数になります。結果として1.5 に2のe-1乗を掛けたもの
,tがゼロの時は
2のe乗
を最近接値に丸めます。
PREC(x)
はこの関数では変更されません。
rndは丸めモード,tはxが計算される際に使われる三種値でなければなりません。
これはmpfr_check_range
関数と同じです。
非正規化エリアとなる指数部の範囲は,emin
からemin+PREC(x)-1
までとなります。
emax
の設定値が小さすぎる場合など,現状のMPFRの許容指数部の範囲内では結果が表現できない時のこの関数
の挙動は定義されていません。
他の関数とは異なり,演算結果は,入力時のxではなく,真値と比較されます。
つまり,三種値は引数の値が引き継がれます。
通常は,返り値の三種値がゼロの場合,不正確フラグが立ちます。 更に,入力値xが最初から非正規化エリアの値だったりして,2回目の丸め処理が起きた場合は アンダーフローフラグがセットされます。
[警告] mpfr_subnormalize
関数を呼び出す前にemin
をmpfr_set_emin
関数で変更してしまうと,
その値がMPFRの現状の指数部範囲に入っているかどうかを確認しなければなりません。
しかし計算の前に
emin
を変更することができることは悪いことではありません。
以下のプログラムは,2進倍精度IEEE 754演算 (IEEE 754-2008のbinary64)をMPFRでエミュレートしたものです。
{ mpfr_t xa, xb; int i; volatile double a, b; mpfr_set_default_prec (53); mpfr_set_emin (-1073); mpfr_set_emax (1024); mpfr_init (xa); mpfr_init (xb); b = 34.3; mpfr_set_d (xb, b, MPFR_RNDN); a = 0x1.1235P-1021; mpfr_set_d (xa, a, MPFR_RNDN); a /= b; i = mpfr_div (xa, xa, xb, MPFR_RNDN); i = mpfr_subnormalize (xa, i, MPFR_RNDN); /* new ternary value */ mpfr_clear (xa); mpfr_clear (xb); }
mpfr_set_emin
関数とmpfr_set_emax
関数は前もって呼び出しておき,
全ての計算すべき値が,現状の指数部範囲に収まっていることを確認しておきましょう。
[警告] 上記のプログラムは非正規化エリアでも正しく丸めを行って倍精度IEEE 754演算を エミュレートしています。 このような動作はハードウェアでは行われません。
下記の例は,特別なケースで固定点小数点演算をエミュレートする方法を示しています。 ここでは,2の-42乗 で丸める固定小数点演算を行って整数の1から17までのサイン(sine)関数の値を 求めています。絶対値としてはほぼ1になってしまうということを利用しています。
{ mpfr_t x; int i, inex; mpfr_set_emin (-41); mpfr_init2 (x, 42); for (i = 1; i <= 17; i++) { mpfr_set_ui (x, i, MPFR_RNDN); inex = mpfr_sin (x, x, MPFR_RNDZ); mpfr_subnormalize (x, inex, MPFR_RNDZ); mpfr_dump (x); } mpfr_clear (x); }
それぞれアンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラーフラグをクリアします。
全てのグローバルフラグ(アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラー)をクリアします。
[注記] フラグのグループをまとめてクリアするためのmpfr_flags_clear
関数も使用可能です。
アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラーフラグを立てます。
それぞれ,対応するフラグ (アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラー )を返します。フラグが立っている時のみ,非ゼロ数を返します。
以下のmpfr_flags_
関数群は,maskという引数を取りますが,これは
例外フラグを自在に操るためのものです。
一つのフラグは,対応するmaskの当該ビットがセットされている時のみ,例外フラグの集合の一部となります。
MPFR_FLAGS_
マクロは,このmaskを設定するために使用されます。Exceptions
もご参照下さい。
maskで指定されたフラグのグループをクリアします。
maskで指定されたフラグのグループを立てます。
maskで指定されたフラグを返します。maskにセットしたフラグが立っているかどうかは,
返り値がゼロかどうかで判断できます。個別のフラグが立っているかどうかの判断は,MPFR_FLAGS_
マクロとのANDを取ることで可能になります。
例)
mpfr_flags_t t = mpfr_flags_test (MPFR_FLAGS_UNDERFLOW| MPFR_FLAGS_OVERFLOW) … if (t) /* アンダーフローかオーバーフロー */ { if (t & MPFR_FLAGS_UNDERFLOW) { /* アンダーフローを制御 */ } if (t & MPFR_FLAGS_OVERFLOW) { /* オーバーフローを制御 */ } }
全てのフラグを返します。これは
mpfr_flags_test(MPFR_FLAGS_ALL)
と同じ意味になります。
maskで特定されたフラグの状態をflagsに格納します。
Next: Custom Interface, Previous: Exception Related Functions, Up: MPFR Interface [Index]
MPFRパッケージに同梱されているmpf2mpfr.hヘッダファイルは,GNU MPが提供するMPF型との互換性を維持するためのものです。
下記のように2行分を#include <gmp.h>
の後に追加します。
#include <mpfr.h> #include <mpf2mpfr.h>
このように使うことで,MPF型を前提として作られたプログラムを,一切変更することなくMPFRでコンパイルすることができるようになります。
全ての計算はデフォルトのMPFR丸めモードの下で行われますので,mpfr_set_default_rounding_mode
関数を使って丸めモードの変更ができます。
[警告] MPF型とMPFRではいくつか異なる点があります。特に下記のようなものが挙げられます。
gmp_printf
関数など)は,任意精度の浮動小数点数型に対しては動作しません。
mpf_t
型はmpf2mpfr.hの中でmpfr_t
型として再定義されます。
xの精度桁数を正確にprecビットに設定し直します。
mpfr_set_prec
関数との違いは,precは仮数部が現状の変数xのメモリ領域に収まる長さになっていると仮定していることです。そうでなければ,この関数の振る舞いは不定となります。
op1とop2とが,ともに通常の浮動小数点数で,等しい指数部を持ち,仮数部の冒頭op3ビットが等しいか,両方ともゼロか,同じ符号を持つ無限大であるか,これらのいずれかであれば,非ゼロ数を返します。 この関数はMPFの対応する関数との互換性のために定義されたもので,それ以外の目的には使用しないことをお勧めします。 この関数は,二数が近接しているかどうかを確認したい時には使用しないで下さい。例えば, 1.011111 と1.100000は,op3が1を超える時には等しくないものとして扱われます。
op1とop2の相対差を計算し,その結果をropに代入します。 この関数は,相対差に関しては正しい丸めを保証しません。 単純に|op1-op2|/op1をropの精度桁数とrnd方式で計算して丸めます。
これらの関数はmpfr_mul_2ui
関数やmpfr_div_2ui
関数と同一のものです。
MPFの互換性のために残された関数なので,その必要がなければmpfr_mul_2ui
関数やmpfr_div_2ui
関数の利用をお勧めします。
Next: Internals, Previous: Compatibility with MPF, Up: MPFR Interface [Index]
幾つかのアプリケーションでは,スタックを使ってメモリやオブジェクトの操作を行います。 しかし,MPFRのメモリデザインは,そういう目的には向いていません。 それ故,その手のアプリケーションでMPFRが使用できるようにするのであれば,補助的なメモリインターフェース がなくてはなりません。それがカスタムインターフェースです。
これらの機能をMPFRで使用できるようにするには,下記の二つの方法があります。
mpfr_t
型の変数を直接スタックに積む。
mpfr_t
型変数を作る。
浮動小数点数を削除するには,使用したメモリをガベージコレクションに為すがままにさせておくしかありません。 全てのメモリ管理機能(割り当て,破壊,解除)はアプリケーションにお任せするのです。
このインターフェースのためのMPFRの機能は,高速性のためにマクロとして実装されています。
例えば,mpfr_custom_init (s, p)
はマクロを使って実行されますが,(mpfr_custom_init) (s, p)
は関数を使用しています。
[注記1] MPFRの関数は,一時的な浮動小数点数用のためにmpfr_init
関数や同様の関数を使って初期化を行います。詳細はGNU MPのカスタムアロケーションの解説を読んで下さい。
[注記2] MPFRの関数は,内部的にキャッシュ用の関数(mpfr_const_pi
関数など)を利用します。
従って,mpfr_init
関数がGMPのカスタムアロケーション機能経由で呼ばれ,アプリケーションのスタック上にメモリが確保されるようであれば,メモリを廃棄する際には毎回mpfr_free_cache
関数を呼ばなくてはなりません。
精度桁数precビットの仮数部を格納するのに必要なバイト数を返します。
精度桁数precビットの仮数部を初期化します。ここで
significandはmpfr_custom_get_size (prec)
バイトのメモリ領域が最低でも必要で,mp_limb_t
型 (GMPのデータ型,see Internals参照)の配列になっていなければなりません。
mpfr_t
型のダミー初期化を実行し,次のように値をセットします。
MPFR_NAN_KIND
の時は,xにはNaNがセットされる。
MPFR_INF_KIND
の時は,xにはkindと同じ符号の
無限大がセットされる。
MPFR_ZERO_KIND
の時は,xにはkindと同じ符号の
ゼロがセットされる。
MPFR_REGULAR_KIND
の時は,xにはkindと同じ符号,指数部と仮数部にはそれぞれexpとsignificandがセットされる。
全ての場合に共通するのは,significandがxを使う以降の計算に直接利用されるということです。
この関数はメモリ領域の確保は行いません。この関数で初期化される浮動小数点数は
mpfr_set_prec
関数やmpfr_prec_round
関数を使ったリサイズや,mpfr_clear
関数を使ったメモリ解放は出来ません。
significandは,同じ精度桁precを引数に渡したmpfr_custom_init
関数を使って初期化しなくてはいけません。
mpfr_custom_init_set
関数を使って生成されたmpfr_t
型データの種類を返します。
mpfr_custom_init_set
関数を使用せずに初期化されたmpfr_t
型データが渡された時の動作は定義されていません。
mpfr_custom_init_set
関数を使って初期化されたmpfr_t
型データの仮数部へのポインタを返します。
mpfr_custom_init_set
関数を使用せずに初期化されたmpfr_t
型データが渡された時の動作は定義されていません。
xが非ゼロの通常の浮動小数点数で,仮数部が[1/2,1)にあると想定される時,xの指数部を返します。
xがNaN,無限大,ゼロのように,mpfr_get_exp
関数の挙動が定義されていない値である時,
返り値は不定となりますが,mpfr_exp_t
型の有効な数になります。
mpfr_custom_init_set
関数を使用せずに初期化されたmpfr_t
型データが渡された時の動作は定義されていません。
MPFRに,xの仮数部がガベージコレクションによって移動され,新しい位置に収まっていると知らせます。
とはいえ,アプリケーション自体が仮数部とmpfr_t
型データを移動するようにしないといけません。
mpfr_custom_init_set
関数を使用せずに初期化されたmpfr_t
型データが渡された時の動作は定義されていません。
Previous: Custom Interface, Up: MPFR Interface [Index]
リム(limb)は,1ワードを単位とする多倍長精度浮動小数点数の構成要素を意味します。
1リムは通常,32ビットか64ビットです。リムを表わすCデータ型はmp_limb_t
です。
mpfr_t
データ型は,内部的には構造体の配列の1つ分として定義されており,mpfr_ptr
型は,この構造体へのポインタを表現しているデータ型です。
mpfr_t
データ型は,次の4つのフィールドから構成されています。
_mpfr_prec
フィールドは,変数の仮数部の精度桁数(ビット数)を保持します。最小値はMPFR_PREC_MIN
です。
_mpfr_sign
フィールドは,変数の符号を保持します。
_mpfr_exp
フィールドには仮数部を格納します。
指数部がゼロの時は,小数点はちょうどMSB(most significant digits)のすぐ上にあることになります。 nが非ゼロの時は,2^nを乗じたところに小数点が移動します。
NaN,無限大,ゼロは,この指数部に特別な値を設定して識別します。
_mpfr_d
フィールドには,LSB(lease significant bits)が先頭に来るリム配列へのポインタが格納されます。
使用するリム数は_mpfr_prec
で決定され,具体的には
ceil(_mpfr_prec
/mp_bits_per_limb
)となります。
非数以外の通常の数はMSL(Most significant limb)のMSB(Most significant bits)が1になります。
精度桁数がリム数とは一致しない時は,余った下のビットは全てゼロにします。
Next: MPFR and the IEEE 754 Standard, Previous: MPFR Interface, Up: Top [Index]
本節では,MPFRのバージョンアップに伴って変化したAPIについて解説し,古いMPFRでもコンパイルできるプログラムの書き方について述べます。 但し,MPFR 2.2.0 (2005年9月20日リリース)以降のものについてのみフォローします。
APIの変更は,バージョン番号の最上位,もしくはその下の桁が変わった時に行われ,パッチレベル の変更(MPFRバージョン番号の第3桁目)では行われません。MPFRの内部構造を利用するようなプログラムでなければ, バグフィックスや意図しない動作による影響以上の変更は行われません。
一般的なルールとして,MPFRを利用するプログラムは,メジャーバージョンアップでも しない限り,多少のアップデートしたMPFRでも動くように書くべきです。廃止予定 と予告されている機能はそのうち使えなくなるので,そのような関数を利用していると,そのうちコンパイルやリンク時にエラーを起こすことになりかねません。 アップデートに伴う変更が原因で結果がおかしくなるようなら,これ以降に 記述してある,使用バージョンに関するFAQやMPFRのWebページにある変更点(最小限度にとどめていますので,ほとんどのソフトウェアでは 影響はないでしょう)を確認してみて下さい。 バグ混入や,既に修正されているものもあります。 特に記述がない場合は,バグ報告を送って下さい(Reporting Bugs 参照)。
しなしながら,現在のMPFRを利用したプログラムは,このマニュアルに書いてある通り, 以前のバージョンのMPFRで動作させる必要はないはずです。 この節では,ポータブルなプログラムを書くための情報を提供します。
[注記] ここに記した情報は網羅的なものではありませんので,APIの変更情報については MPFRのそれぞれのバージョンごとに提供されるNEWSファイルを参照して下さい。諸々の 更新情報も併せて掲載されています。
• Type and Macro Changes: | データ型とマクロの変更 | |
• Added Functions: | 追加された関数 | |
• Changed Functions: | 変更された関数 | |
• Removed Functions: | 削除された関数 | |
• Other Changes: | その他の変更 |
Next: Added Functions, Previous: API Compatibility, Up: API Compatibility [Index]
指数部の公式なデータ型をmp_exp_t
からmpfr_exp_t
に変更したのはMPFR 3.0からです。
mp_exp_t
データ型はGMPではこれからも違った意味で使用されると思われます。
この二つのデータ型は現状同じものです(mpfr_exp_t
はtypedef
でmp_exp_t
が指定されている)
ので,mp_exp_t
を指数部のデータ型として使用することは今でも可能でが,将来は変更されるかもしれません。
代わりに,mpfr.hをインクルードした後で
mpfr_exp_t
型がMPFR 2.xで使用されることがないよう,次の指定を行うと良いでしょう。
#if MPFR_VERSION_MAJOR < 3 typedef mp_exp_t mpfr_exp_t; #endif
公式の精度桁数と丸めモードデータ型はそれぞれmp_prec_t
とmp_rnd_t
から,
mpfr_prec_t
とmpfr_rnd_t
に,MPFR 3.0で変更されました。
この変更はMPFRでは大分以前から行わており,少なくともMPFR 2.2.0では下記のような
コードがmpfr.h:に入っています。
#ifndef mp_rnd_t # define mp_rnd_t mpfr_rnd_t #endif #ifndef mp_prec_t # define mp_prec_t mpfr_prec_t #endif
上記コードの意味は,新しい公式データ型であるmpfr_prec_t
型とmpfr_rnd_t
型をあなたのプログラムで安全に使用することができる,というものです。
データ型mp_prec_t
と mp_rnd_t
(MPFRでのみ使用可能)は将来的に削除
されるかもしれません。mp_
という名前はGMPで予約されているものですから。
精度桁数のデータ型mpfr_prec_t
(mp_prec_t
)は,MPFR 3.0より前は符号なし(unsigned)
でしたが,現在は符号付き(signed)です。MPFR_PREC_MAX
は変更されていません。
実際,MPFRのソースコードはMPFR_PREC_MAX
が指数部のデータ型で表現可能であることを
要求しており,これはmpfr_prec_t
と同じデータサイズですが,常に符号付きでした。
従って,新旧のMPFRバージョンを通じて使用できるプログラムを書くのであれば,
mpfr_prec_t
の符号あるなしに左右されないようにしましょう。
通常の演算における型変換を考えた場合,符号なしデータ型を符号付きデータ型に変更するのは有効で,
負数を通常の方法で型変換した時に,正しくない結果を招くことが防止できます。
[警告] 内部的にあろうが表面的にであろうが,mpfr_prec_t
が符号付きであるという前提で
プログラムを書くと,MPFR 2.xでコンパイルして実行した時に影響が出る可能性があります。
丸めモード名GMP_RNDx
は,MPFR 3.0でMPFR_RNDx
に変更されました。
しかしながら旧名GMP_RNDx
も互換性を保つために有効になっています(が,将来変更するかも)。
実際下記のような定義がされています。
#define GMP_RNDN MPFR_RNDN #define GMP_RNDZ MPFR_RNDZ #define GMP_RNDU MPFR_RNDU #define GMP_RNDD MPFR_RNDD
丸めモード「ゼロから遠ざかる丸め」 (MPFR_RNDA
)は
MPFR 3.0で追加されました。ですが,GMP_RNDA
という定義はありません。
忠実丸め(MPFR_RNDF
)はMPFR 4.0で追加されましたが,現状では部分的なサポートにとどまっています。
MPFR_FLAGS_
という名前で始まるフラグ関連のマクロはMPFR 4.0で追加されました。
新しい関数mpfr_flags_clear
,mpfr_flags_restore
, mpfr_flags_set
,mpfr_flags_test
も同様です。
Next: Changed Functions, Previous: Type and Macro Changes, Up: API Compatibility [Index]
ここでは,アルファベット順に,MPFR 2.2以降に追加されてきた関数と関数ライクなマクロを,追加時のMPFRバージョンと共に列挙します。
mpfr_add_d
関数はMPFR 2.4で追加。
mpfr_ai
関数はMPFR 3.0で追加 (不完全な実験的実装)。
mpfr_asprintf
関数はMPFR 2.4で追加
mpfr_beta
関数はMPFR 4.0 で追加(不完全な実験的実装)
mpfr_buildopt_decimal_p
関数はMPFR 3.0で追加。
mpfr_buildopt_float128_p
関数はMPFR 4.0で追加。
mpfr_buildopt_gmpinternals_p
関数はMPFR 3.1で追加。
mpfr_buildopt_sharedcache_p
関数はMPFR 4.0で追加。
mpfr_buildopt_tls_p
関数はMPFR 3.0で追加。
mpfr_buildopt_tune_case
関数はMPFR 3.1で追加。
mpfr_clear_divby0
関数はMPFR 3.1で追加(新しいゼロ除算例外追加も)。
mpfr_copysign
関数はMPFR 2.3で追加。
[注記] MPFR 2.2で既にmpfr_copysign
関数は使用可能になっていましたが,
マニュアルには明記しておらず,動作も少し異なっていました(2番目の引数がNaN
の場合)。
mpfr_custom_get_significand
関数はMPFR 3.0で追加。
この関数は以前のバージョンでmpfr_custom_get_mantissa
関数と命名されました。
現在でもmpfr.hのマクロとして,この名前で使用可能です。
#define mpfr_custom_get_mantissa mpfr_custom_get_significand
上記の定義から分かるように,MPFR 2.x と MPFR 3.x ではmpfr_custom_get_mantissa
を
使って下さい。
mpfr_d_div
関数とmpfr_d_sub
関数はMPFR 2.4で追加。
mpfr_digamma
関数はMPFR 3.0で追加。
mpfr_divby0_p
関数はMPFR 3.1で,新たにゼロ除算例外機能付きで追加。
mpfr_div_d
関数はMPFR 2.4で追加。
mpfr_erandom
関数はMPFR 4.0で追加。
mpfr_flags_clear
関数,mpfr_flags_restore
関数,
mpfr_flags_save
関数, mpfr_flags_set
関数,mpfr_flags_test
関数は
MPFR 4.0で追加。
mpfr_fmma
関数とmpfr_fmms
関数はMPFR 4.0で追加。
mpfr_fmod
関数はMPFR 2.4で追加。
mpfr_fmodquo
関数はMPFR 4.0で追加。
mpfr_fms
関数はMPFR 2.3関数で追加。
mpfr_fpif_export
関数とmpfr_fpif_import
関数はMPFR 4.0で追加。
mpfr_fprintf
関数はMPFR 2.4で追加。
mpfr_free_cache2
関数はMPFR 4.0で追加。
mpfr_free_pool
関数はMPFR 4.0で追加。
mpfr_frexp
関数はMPFR 3.1で追加。
mpfr_gamma_inc
関数はMPFR 4.0で追加。
mpfr_get_float128
関数はMPFR 4.0で追加。
オプション‘--enable-float128’付きで設定してビルドすると使用できます。
mpfr_get_flt
関数はMPFR 3.0で追加。
mpfr_get_patches
関数はMPFR 2.3で追加。
mpfr_get_q
関数はMPFR 4.0で追加。
mpfr_get_z_2exp
関数はMPFR 3.0で追加。
この関数は,以前のバージョンではmpfr_get_z_exp
という名前でした。
mpfr_get_z_exp
関数も,下記のようにmpfr.hでマクロとして定義
されていますので,今でも使用可能です。
#define mpfr_get_z_exp mpfr_get_z_2exp
従って,MPFR 2.xとMPFR 3.xの両方を使って動作するプログラムはmpfr_get_z_exp
関数の方を使うべきです。
mpfr_grandom
関数はMPFR 3.1で追加。
mpfr_j0
関数, mpfr_j1
関数,mpfr_jn
関数はMPFR 2.3で追加。
mpfr_lgamma
関数はMPFR 2.3で追加。
mpfr_li2
関数はMPFR 2.4で追加。
mpfr_log_ui
関数はMPFR 4.0で追加。
mpfr_min_prec
関数はMPFR 3.0で追加。
mpfr_modf
関数はMPFR 2.4で追加。
mpfr_mp_memory_cleanup
関数はMPFR 4.0で追加。
mpfr_mul_d
関数はMPFR 2.4で追加。
mpfr_nrandom
関数はMPFR 4.0で追加。
mpfr_printf
関数はMPFR 2.4で追加。
mpfr_rec_sqrt
関数はMPFR 2.4で追加。
mpfr_regular_p
関数はMPFR 3.0で追加。
mpfr_remainder
関数とmpfr_remquo
関数はMPFR 2.3で追加。
mpfr_rint_roundeven
関数とmpfr_roundeven
関数はMPFR 4.0で追加。
mpfr_round_nearest_away
関数はMPFR 4.0で追加。
mpfr_rootn_ui
関数はMPFR 4.0で追加。
mpfr_set_divby0
関数は,新たにゼロ除算例外機能付きでMPFR 3.1で追加。
mpfr_set_float128
関数はMPFR 4.0で追加。
‘--enable-float128’オプション付きでビルドすると使用できます。
mpfr_set_flt
関数はMPFR 3.0で追加。
mpfr_set_z_2exp
関数はMPFR 3.0で追加。
mpfr_set_zero
関数はMPFR 3.0で追加。
mpfr_setsign
関数はMPFR 2.3で追加。
mpfr_signbit
関数はMPFR 2.3で追加。
mpfr_sinh_cosh
関数はMPFR 2.4で追加。
mpfr_snprintf
関数とmpfr_sprintf
関数はMPFR 2.4で追加。
mpfr_sub_d
関数はMPFR 2.4で追加。
mpfr_urandom
関数はMPFR 3.0で追加。
mpfr_vasprintf
関数, mpfr_vfprintf
関数, mpfr_vprintf
関数,
mpfr_vsprintf
関数,mpfr_vsnprintf
関数はMPFR 2.4で追加。
mpfr_y0
関数, mpfr_y1
関数,mpfr_yn
関数はMPFR 2.3で追加。
mpfr_z_sub
関数はMPFR 3.1で追加。
Next: Removed Functions, Previous: Added Functions, Up: API Compatibility [Index]
ここに記した関数はMPFR 2.2以降に変更がなされています。これらの変更により, 使用するMPFRのバージョンとの組み合わせ次第でプログラムの挙動が変わるかもしれません。
mpfr_abs
関数, mpfr_neg
関数,mpfr_set
関数は,MPFR 4.0で変更されました。
以前のMPFRバージョンでは,NaNの符号ビットは不定でしたが,
実用的になるよう,マニュアルに記述したように規定されるようになりました。但し,mpfr_neg
関数
に対して引数をmpfr_neg(x,x,rnd)
の
ように再利用した場合は除きます。
mpfr_check_range
関数はMPFR 2.3.2とMPFR 2.4で変更されました。
値が不正確な無限大の場合,現在はオーバーフローフラグが立っていない場合はセットされますが,
以前は変更なしのままでした。
これは実用上期待されているもの(かつ,MPFRのソースコードで必要としていたもの)ですが,
かつての動作がバグであると見なされてるようになったため,MPFR 2.3.2で変更されました。
mpfr_eint
関数はMPFR 4.0で変更されました。
現在はE1の値とと,負の引数に対してはeint1関数の値を返します。MPFR 4.0より前のバージョンではNaNを返していました。
mpfr_get_f
関数はMPFR 3.0で変更されました。
以前は,ゼロを返していましたが,NaNや無限大のようにMPF型には存在しない特殊値には対応していませんでした。
現在では特殊値に対しては範囲エラーフラグが立てられ,
mpfr_get_f
関数は通常の三種値を返します。
mpfr_get_si
関数, mpfr_get_sj
関数, mpfr_get_ui
関数,
mpfr_get_uj
関数はMPFR 3.0で変更されました。
以前のバージョンでは,範囲エラーフラグが立つケースでは決まっていませんでした。
mpfr_get_str
関数はMPFR 4.0で変更されました。
現在では,NaNが入力値の時はNaNが返されます。これはNaNに関するMPFRのルールと
IEEE 754-2008の推奨する文字列変換(5.12.1項)に基づいた規則です。変換に際して丸め誤差が入ると,不正確フラグが立てられます。
mpfr_get_z
関数はMPFR 3.0で変更されました。
以前の返り値はvoid
型でしたが,現在はint
型になり,通常の三種値が返されます。
従って,
MPFR 2.x と 3.x の両方で動作するプログラムは,この関数の返り値を利用してはいけません。
この場合でも,
mpfr_get_z
関数を使って,条件演算子の2番目,もしくは3番目の項指定するようなCプログラムは
影響を受けます。例えば,下記のプログラムはMPFR 3.0では正常に動きますが,MPFR 2.xではうまく動きません。
bool ? mpfr_get_z(...) : mpfr_add(...);
一方,下記の例はMPFR 2.xでは正常に動きますが,MPFR 3.0ではうまくいきません。
bool ? mpfr_get_z(...) : (void) mpfr_add(...);
ポータブルなプログラムを書きたければ,mpfr_get_z(...)
をvoid
型にキャストして,
下記のように条件演算子の両方の項をvoid
型にします。
bool ? (void) mpfr_get_z(...) : (void) mpfr_add(...);
条件演算子の代わりに,if ... else
も使用可能です。
さらに,範囲エラーフラグが立てられる場合は,MPFR 2.xでは特に定められていませんでした。
mpfr_get_z_exp
関数はMPFR 3.0で変更されました。
以前のMPFRのバージョンでは,範囲エラーフラグが立つケースは特に定められていませんでした。
[注記] この関数はMPFR 3.0でmpfr_get_z_2exp
という名前に変更されましたが,
mpfr_get_z_exp
関数も互換性維持のためにまだ使用できます。
mpfr_set_exp
関数はMPFR 4.0で変更されました。
MPFR 4.0より前のバージョンでは,指数部は,引数に指定したMPFRオブジェクトの
内容が何であれ,設定されていました。
実用的には,MPFR数を,内部構造の各フィールドごとに作り上げていくときには,
低レベル関数としては便利に使えますが,APIとしては,内部構造を利用する場合を除いて
そのような機能は提供しません。従って,APIに対してはこの関数のような機能は無用の長物で,
NaN,無限大,ゼロのような特殊数を使用するMPFRでは,不正なフォーマットの値を作って
しまうかもしれません。
mpfr_strtofr
関数はMPFR 2.3.1とMPFR 2.4で変更されました。
行われたのはバグフィックスで,ソースコードとマニュアルの記述が食い違っていましたが,
整合性を取り,有用な動作になるように,両方を修正しました。
ソースコードの主要な変更点は次の通りです。
2進表現の指数部を,0b
や
0x
のようなプレフィックスなしでも受け付けるようにしました。
また,以前は不正としていた符号付きNaNに対応するデータにも対応しました。
mpfr_strtofr
関数はMPFR 3.0で変更されました。
今では基数として37から62も受け付けるようになっています(これ以外の基数の場合については変更ありません)。
[注記] サポート外の基数が与えられた時のこの関数の挙動は不定です。正確に言うと,MPFR 2.3.1以降では アサーションによる失敗を発生させます。この挙動については将来変更される可能性があります。
mpfr_subnormalize
関数はMPFR 3.1で変更されました。
行われたのはバグフィックスです。mpfr_subnormalize
関数は,MPFR 3.0.0までは
フラグは立てませんでした。特に,不正確フラグについては一般的なルールに従っていません
でしたし,特に挙動も指定されていませんでした。
アンダーフローフラグについてはもっと何も定まっていませんでした。
mpfr_sum
関数はMPFR 4.0で変更されました。
mpfr_sum
関数はMPFR 4.0で完全に書き直され,仕様もアップデートされました。
演算結果が完全にゼロになる時の符号が規定され,返り値も通常の三種値になっています。
旧mpfr_sum
関数の実装も,全てのメモリ上の値を扱うようになっていましたが,
大きさのばらつきが大きい入力に対してはクラッシュする可能性がありました。
mpfr_urandom
関数とmpfr_urandomb
関数はMPFR 3.1で変更されました。
この二つの関数の振る舞いは環境に依存しないようになっています。
但し,GMPの乱数生成器も環境依存ではないという前提です。GMP 4.1から4.2までのバージョンでは,
gmp_randinit_default
が使われているので環境依存になっています。
結果として, 返り値は,MPFR 3.1と,それ以前のバージョンのMPFRとでは違うものになることがあります。
[注記] MPFR 3.1より前では,これらの関数における値の再現性は特別指定していませんでした。従って,MPFR 3.1での動作も 以前のバージョンとの互換性は考えていません。
mpfr_urandom
関数はMPFR 4.0で変更されました。
次の乱数の状態は,現在の指数部の範囲と丸めモードとには依存せずに決まります。
乱数の丸めに伴う例外は,一様分布に従って正しく生成されるようになりました。
結果として,返される乱数は,MPFR 4.0とそれ以前のバージョンとでは異なる可能性があります。
Next: Other Changes, Previous: Changed Functions, Up: API Compatibility [Index]
mpfr_random
関数とmpfr_random2
関数はMPFR 3.0で削除されました。
この変更はMPFR 3.0より前のバージョン用に作った古いプログラムだけに影響します。
mpfr_random
関数はMPFR 2.2.0以降から,mpfr_random2
関数はMPFR 2.4.0以降から,
使用しないよう警告されています。
mpfr_add_one_ulp
関数やmpfr_sub_one_ulp
関数といったマクロは
MPFR 4.0で削除されました。これらの関数は,既にMPFR 2.1.0でマニュアルに掲載
しておりませんし,MPFR 3.1.0以降は無効になった旨,明記されています。
mpfr_grandom
関数はMPFR 4.0で廃止予定の警告が出ています。
以降のバージョンアップで廃止される予定です。
Previous: Removed Functions, Up: API Compatibility [Index]
C++コンパイラを使うのであれば,intmax_t
を検出する方法がMPFR 3.0で変更された
ことに留意して下さい。
MPFR 2.xでは,INTMAX_C
マクロ,もしくは,UINTMAX_C
マクロが定義されている時
,つまり,<stdint.h>
もしくは <inttypes.h>
をインクルードする前に__STDC_CONSTANT_MACROS
マクロが
定義されている時は,
intmax_t
は既に定義されているものと仮定します。
しかし,必ずしもこの仮定は正しくありません。正確に言うと,intmax_t
は,Boostライブラリのように,名前空間std
でのみ定義されていますので,コンパイルに失敗します,
従って,C++コンパイラでINTMAX_C
もしくは UINTMAX_C
のチェックするのは止め,次の方法を試して下さい。
intmax_t
型が必要なMPFR 2.xを使ったプログラムは,MPFR 3.0
以降ではコンパイルできないものと考えて下さい。mpfr.hをインクルード
する前に,#define MPFR_USE_INTMAX_T
が必要になります。
intmax_t
とuintmax_t
の定義をグローバルな
名前空間で行うと良いかもしれません。
ゼロ除算例外はMPFR 3.1で新たに追加されたものですが,この例外を使うのは このバージョン以降に追加された新しい関数だけなので,この導入によって互換性に 問題が生じることはありません。
MPFR 3.1以降では,mpfr.hヘッダファイルを複数回インクルードできます。また 追加された関数もあります (Headers and Libraries 参照)。
MPFRのメモリ割り当て方法については,MPFR 4.0で整理されたものをそのまま順守すべきです。
Next: Contributors, Previous: API Compatibility, Up: Top [Index]
この節では,MPFRとIEEE 754規格の相違点と,IEEE 754ではまだ規定がない挙動について解説します。
MPFRでは原則として非正規化数を使用しません。IEEE 754より広い指数部が扱えるので,IEEE 754より非正規化数のメリットがなく,実装が面倒だからです。但し, mpfr_subnormalize
関数を使って非正規化数のエミュレートはできるようになっています。
MPFRにはNaN が一種類しかありません。基本的には,状態によって,シグナルNaN(sNaN)か沈黙NaN(qNaN)と機能を持ちます。NaNを返す全ての関数(NaNを生成,もしくはコピーしたりする)はNaNフラグを立てます。IEEE 754の場合は,たとえシグナルNaNであっても,何も実行しません。
mpfr_rec_sqrt
関数はIEEE 754とは異なり,入力値が-0である場合は,+0が入力されたときと同じく+Infを返します。IEEE 754では通常の極限値計算結果に従って-Infを返します。
mpfr_root
関数はIEEE 754-2008規格が固まる前に作ったものなので,n乗根の
扱いが異なります。なるべくmpfr_rootn_ui
関数を使って下さい。
符号なしのゼロを用いた演算: 引数として整数型や有理数型を取る関数においては,
浮動小数点数のゼロと異なり,符号なしのゼロしかありません。unsigned long
型でも同じく,数学的にはゼロはゼロ。対して,浮動小数点数のゼロは,アンダーフローの結果
そうなることもあり,非ゼロ数の符号と同じものがついている訳です。
従って,本マニュアルに明記してなくても,最初にmpfr_set_ui
関数やmpfr_set_si
関数で変換された結果,+0として扱われます。これは数学的な意味での極限値とは異なるものに
なっています。但し,加減算(mpfr_add_ui
等々)に対しては当てはまりませんので,
+0も-0も同一のものとして扱います。
このような演算結果をもたらすMPFRの現時点における仕様は,IEEE754規格の枠外のもので,IEEE 754改定を行う浮動小数点演算ワーキンググループでは議論したくない代物だったようです。
MPFRでは,変数ごとに自身の精度桁数を持ち,この点IEEE754規格とは全く異なっているという事実も思い出して下さい。例えば,同一符号を持つ二数の減算を行うと,オーバーフローが発生する可能性があります。同様に,mpfr_set
関数,mpfr_neg
関数,mpfr_abs
関数でも,精度桁数が少ないとオーバーフローが起きるかもしれません。
Next: References, Previous: MPFR and the IEEE 754 Standard, Up: Top [Index]
MPFRのメイン開発陣は,Guillaume Hanrot, Vincent Lefèvre, Patrick Pélissier, Philippe Théveny,そしてPaul Zimmermannです。
Sylvie Boldo(仏,ENS-Lyon)はmpfr_agm
関数とmpfr_log
関数の開発を行いました。
Sylvain Chevillardはmpfr_ai
関数の開発を担当しました。
David Daneyは双曲線関数,逆双曲線関数,2のべき乗関数,階乗関数の開発を行いました。
Alain Delplanqueは新たなmpfr_get_str
関数を開発しました。
Mathieu Dutourはmpfr_acos
関数, mpfr_asin
関数,
mpfr_atan
関数,以前のmpfr_gamma
関数を開発しました。
Laurent Fousseはmpfr_sum
関数のオリジナルバージョン(MPFR 3.1以前)の開発を行いました。
Emmanuel Jeandel(ENS-Lyon)は汎用の幾何級数コード,mpfr_exp3
内部関数,三角関数の初期バージョンの開発,
mpfr_const_log2
関数やmpfr_const_pi
関数の改良を行いました,
Ludovic Meunierはmpfr_erf
関数プログラムの設計の助力を行いました。
Jean-Luc Rémyはmpfr_zeta
関数を開発しました。
Fabrice Rouillierはmpfr_xxx_z
関数,mpfr_xxx_q
関数の開発を行いました。また,Microsoft Windowsへの
移植の助力も行いました。
Damien Stehléはmpfr_get_ld_2exp
関数を開発しました。
Charles Karneyはmpfr_nrandom
関数とmpfr_erandom
関数を開発しました。
Jean-Michel MullerとJoris van der Hoevenには,本プロジェクトの初期段階で実り多き 議論にお付き合い頂き,感謝しています。Torbjörn Granlund とKevin Rydeは本ライブラリの設計に関して助力を惜しみませんでした。 Nathalie Revolは本ドキュメントの草稿を丁寧に読んでいただきました。 Kevin Rydeは,こと,2002年から2004年にかけて,MPFRのポータビリティに関して多大なる貢献を惜しみませんでした。
MPFRライブラリの開発は,INRIA, LORIA (Nancy, 仏),LIP (Lyon, 仏)研究所からの継続的なサポートなしでは不可能なプロジェクトでした。主要開発陣は,LORIAのPolKA, Spaces, Cacao, Caramel,Carambaプロジェクトチームや,LIPのArénaire,AriCプロジェクトチームのメンバーなどから構成されています。 本プロジェクトは,INRIAのFiable (reliableの仏語)活動の一つとして開始され,AOC活動の一つとして継続されてきたものです。 MPFRの開発は,様々な資金の支援を受けて行われてきました。以下列挙しますと, 2002年,Conseil Régional de Lorraine の202F0659 00 MPN 121支援金, 2003-2005年,INRIAより"associate engineer"支援金, 2007-2009年,"opération de développement logiciel"支援金, 2009-2010年, Sylvain Chevillardのポスドク支援金 です。
2012年6月のMPFR-MPCワークショップは,Andreas Engeが受けたERC grant ANTICSより一部補助されて行われました。
2013年1月のMPFR-MPCワークショップは, ERC
grant ANTICS, GDR IMとCaramelプロジェクトチームからの補助を受けて行われましたが,この間,
Mickael GastineauはMPFRbenchプログラムを開発し,
Fredrik Johannssonはより高速なmpfr_const_euler
関数を開発しました。
Next: GNU Free Documentation License, Previous: Contributors, Up: Top [Index]
Next: Concept Index, Previous: References, Up: Top [Index]
Copyright © 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.
This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.
We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.
This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.
A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.
A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.
The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.
The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.
A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.
Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.
The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.
A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.
The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.
You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.
You may also lend copies, under the same conditions stated above, and you may publicly display copies.
If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.
If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.
If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.
It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.
You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:
If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.
You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.
You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.
The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.
You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.
The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.
In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”
You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.
You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.
A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.
If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.
Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.
If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.
You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.
The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/.
Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation.
To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:
Copyright (C) year your name. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''.
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with...Texts.” line with this:
with the Invariant Sections being list their titles, with the Front-Cover Texts being list, and with the Back-Cover Texts being list.
If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.
If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.
Next: Function and Type Index, Previous: GNU Free Documentation License, Up: Top [Index]
Jump to: | A B C E F G I L M O P R S T U |
---|
Jump to: | A B C E F G I L M O P R S T U |
---|
Previous: Concept Index, Up: Top [Index]
Jump to: | M |
---|
Jump to: | M |
---|