Next: , Previous: (dir), Up: (dir)

GNU MPFR

このマニュアルは,MPFR(Multiple Precision Floating-point Reliable)ライブラリ Version 4.0.1のインストール方法,及び,使用方法を記述したものです。

Copyright 1991, 1993-2018 Free Software Foundation, Inc.

本マニュアルの複写,配布,改変は,GNU Free Documentation License Version 1.2以降の 条項の元で許可されています。但し,不変の節,表紙の文,裏表紙の文を改変して はいけません。本マニュアルにはGNU Free Documentation Licenseも入っています。



Next: , Previous: Top, Up: Top

MPFRの著作権について

GNU MPFRライブラリ(MPFRと略す)は フリーです。フリーとは,万人が自由に使用でき,自由な基盤の上で,再配布も 自由にできるという意味です。 本ライブラリはパブリックドメインではありません。つまり,著作権で守られており, 再配布には制限があります。しかしその制限は,良き協力者たる市民が行おうとする全ての 行為を許容するように設計されています。許されないのは, あなたから入手したあらゆるバージョンの本ライブラリを,更に広く共有する行為を妨害することだけです。

特に,我々は次のことを確認したいと考えています。あなたは本ライブラリのコピーを手放す権利があり, 欲しい時にソースコードなどを受け取り,新しいフリーなプログラムを作るために本ライブラリの 改変を行ったり,一部を利用したりすることができる,ということを知っているのです。

万人が上記の権利を持っているということを知らしめるため,我々は,あなたが,他の人達からこれらの権利を剥奪することを禁止します。例えば,あなたがGNU MPFRライブラリのコピーを配布 するのであれば,それを受け取った人達にも,あなたが有する全ての権利を与えなければなりません。 そして,受け取った人たちもまた,元のソースコードを入手できるということを確認しなければなりません。 更に,あなたは彼らにそのことを周知しなくてはなりません。

また,我々自身を保護するため,GNU MPFRライブラリは無保証であることを周知させなくてはなりません。 本ライブラリを改良して放出した場合,我々は,それがもとの配布物とは別物であることを知って頂きたいと思います。 そうすることで,改良の結果生じた諸問題によって我々の評判が貶められることはなくなります。

GNU MPFRライブラリのライセンスの正確な著作権の条項については, ソースコードに付随する劣等GPL(Lesser General Public License)に書いてあります。COPYING.LESSERファイルを参照して下さい。


Next: , Previous: Copying, Up: Top

1 MPFRについて

MPFRはポータブルなCライブラリで,任意精度の浮動小数点演算を行います。その基盤ライブラリとしてGNU MP(GMP)を使用しています。 MPFRの目的は,緻密な方針に基づいた浮動小数点数クラスを提供することにあり,下記に示すように,他の任意精度浮動小数点ソフトウェアとは異なる特徴があります。

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ライブラリとリンクするための方法も一緒に配布する必要があります。

1.1 本マニュアルの使い方

まずMPFR Basicsは読んで下さい。MPFRのインストールを自力で行う必要がある場合は, Installing MPFRにも目を通して下さい。MPFRライブラリの使用時にはMPFR Interfaceが参考になるでしょう。

本章以降の記述は後々の参照用ですが,一通り目を通しておくと良いでしょう。


Next: , Previous: Introduction to MPFR, Up: Top

2 MPFRのインストール

MPFRライブラリは,GNU/Linuxディストリビューションには予めインストールされていることが 多くなりました。しかし,開発用に必要なmpfr.h等のファイルが入っていないことは ままあります。MPFRがフルでインストールされているかどうかを確認するには,/usr/includempfr.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をインストールしたい 時には,次の節に示す手順でやってみて下さい。

2.1 インストール方法

この節では,UNIXシステムにMPFRをインストールするための手続きを説明します。 詳細はINSTALLファイルをご覧下さい。

  1. MPFRのビルドには,まずGNU MP(Version 4.1以降)のインストールが必要になります。 Cコンパイラは不可欠で,GCCをお勧めしますが,普通に使えるコンパイラであれば問題 ないでしょう。またUNIX標準の‘make’コマンドも必要ですし, 他にもUNIX標準のユーティリティ コマンド類が必要になります。

    以上の準備ができたら,MPFRのビルド用ディレクトリで,下記のコマンドを実行しましょう。

  2. ./configure

    これによって,ビルドの準備が完了し,貴方のシステムにふさわしいオプションがセットアップされます。 インストールディレクトリ(デフォルトは/usr/local)や,スレッドのサポートなど,デフォルトとは 異なるオプションを指定することも可能です。詳細についてはINSTALLファイルや,‘./configure --help’ の出力結果をご覧下さい。エラーメッセージが出た時もこの辺りの記述を参照して下さい。

  3. make

    このコマンドでMPFRをコンパイルし,ライブラリアーカイブファイルであるlibmpfr.aを生成します。 大方の環境では,動的ライブラリ(dynamic library)も一緒に生成されます。

  4. make check

    このコマンドは,MPFRのビルドが正常に行われたかどうかを確認します。 確認に失敗した時は,どこでどのようにコケているかを tests/test-suite.logファイルで調べることができます。このファイルの中身を 自動的に出力したい時には,予め‘VERBOSE’環境変数を1にセットしてから‘make check’ を実行します。例えば次のように打ち込んで下さい。

    VERBOSE=1 make check

    コケた時にはその要因が既知のものかどうかを知りたいと思うのが人情ですよね?(つか,調べて下さいな)。 未知の要因によるものでしたら,MPFRメーリングリスト ‘mpfr@inria.fr’に報告をお願いします。詳細はSee Reporting Bugsをご覧下さい。

  5. make install

    これを実行することで,mpfr.hmpf2mpfr.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の代わりに使用します。

2.2 その他の`make'オプション

以上で示したもの以外にも有用なmakeオプションがあります。

2.3 ビルド時のトラブル

何かしらトラブった時には,バグだと騒ぎ立てる前にINSTALLファイル,特に,「問題が起こった時には」の節を 熟読して下さい。 MPFRに限らず,ユーザー側でヘンな設定を行っているためにトラブルが発生してしまうことがあります。 MPFRサイトのFAQ http://www.mpfr.org/faq.htmlにも,トラブルについての記載があります。

トラブルの報告はMPFRのメーリングリスト‘mpfr@inria.fr’宛にお願いします (See Reporting Bugs)。 修正済みのバグは, MPFR 4.0.1のWebページhttp://www.mpfr.org/mpfr-4.0.1/に掲載されています。

2.4 MPFR最新バージョンの入手先

MPFRの最新バージョンは https://ftp.gnu.org/gnu/mpfr/ もしくは http://www.mpfr.org/から入手できます。


Next: , Previous: Installing MPFR, Up: Top

3 バグ報告

MPFRライブラリにバグを発見したと思ったら,まずはMPFR 4.0.1 Webページhttp://www.mpfr.org/mpfr-4.0.1/ と,FAQ http://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: , Previous: Reporting Bugs, Up: Top

4 MPFRの基本


Next: , Previous: MPFR Basics, Up: MPFR Basics

4.1 ヘッダファイルとライブラリファイル

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.hgmp.hより前でインクルードすべきです。 あるいは,MPFR_USE_FILE (MPFR I/O 関数で必要) や MPFR_USE_VA_LIST (va_listパラメータを使用するMPFR関数で必要)を mpfr.hより前で定義しておくという手もあります。 つまり,mpfr.hをインクルードするような独自のヘッダファイルを作るのであれば, 後者の方法を使う必要があるわけです。

MPFRのマクロを呼び出す際には,使用してはいけないキーワード(現時点ではdowhilesizeofなど)と同じ名前のマクロを定義しないようにしましょう。

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: , Previous: Headers and Libraries, Up: MPFR Basics

4.2 用語とデータ型

浮動小数点数(floating-point number)(短くfloatとも称します)は 任意長の有効小数部(仮数部とも呼ぶ)と,固定長の指数部で構成されています。 mpfr_tというCのデータ型がそれにあたります。内部的には構造体を要素とする 一つ分の配列になっており,mpfr_ptrというCのデータ型は,この構造体への ポインタを表現しています。浮動小数点数には3種類の特殊な値,即ち, 非数(Not-a-Number, NaN)と正負の無限大が存在しています。非数は初期化されていない オブジェクト,不正な演算処理(正の無限大 - 正の無限大 等),不定な値(負の無限大 - 正の無限大 等) に割り当てられます。また,IEEE754規格に倣い,+0や−0のように,ゼロにも符号が付加されます。他のMPFR 関数の挙動もIEEE754規格に準拠しています。規格には明示されていませんが,NaNの符号は不定となります。

精度桁数(precision)は,浮動小数点数の有効小数部のビット数を意味します。Cのデータ型としてはmpfr_prec_tを使用します。 精度桁数はMPFR_PREC_MINから MPFR_PREC_MAXまでの範囲の任意の整数値に設定できます。現在の実装ではMPFR_PREC_MINは1となっています。

[警告] MPFRは内部で精度桁数を増やして計算する必要があります。こうすることで,正確な演算結果(特に,正しく丸めたもの)を返すことができる訳です。従って,精度桁数をMPFR_PREC_MAX付近に設定しないようにして下さい。さもないと,アサーションエラーを誘発してしまいます。また,使用環境のメモリ限度目一杯まで使用することは避けて下さい。プログラムが強制終了されたり,クラッシュしたり,Cプログラムによっては訳の分からない挙動を引き起こすことになりかねません。

丸めモード(rounding mode)は,浮動小数点演算結果を丸める方式を定めるものです。丸めは,演算結果がそのまま有効小数部に収まり切れない時に実行されます。丸めモードを表わすCのデータ型はmpfr_rnd_tです。

MPFRはグローバルに,もしくはスレッドごとにフラグを保持しており,サポートしている例外をここで判別します(Exceptions)。 フラグのCデータ型は,複数のフラグやビットマスクを一括して表現できるようになっています。


Next: , Previous: Nomenclature and Types, Up: MPFR Basics

4.3 MPFR変数のデータ変換

MPFR変数を割り当てる前に,初期化のための関数を呼び出す必要があります。変数が用済みになった際には,当該変数を消去する関数を呼び出す必要があります。 変数の初期化は一回だけにしておきましょう。何度も初期化しようとすると,その間に消去関数を呼ぶ必要が出てきます。一度初期化された変数に対しては何度でも値を代入することができます。

動作が遅くならないよう,変数の初期化と消去をループ内で繰り返さず,ループに入る前に一度だけ初期化を行い,ループを抜けてから変数を消去するようにしましょう。

MPFR変数用に追加的なメモリスペースを確保する必要はありません。どんな精度桁数の変数でも,仮数部は固定サイズで確保されます。従って,精度桁数の変更,初期化,再初期化等をしない限り,変数が有効である間は使用メモリ量は変化しません。

一般に,全てのMPFR関数の引数の並び順は,前の方が出力用,その後ろに入力用となります(訳注:LAPACKやBLASとは真逆)。これは,代入演算子に倣った作法です。 MPFRの場合,同一の関数の引数として,入力用・出力用に同じ変数を指定することも可能です。例えば,浮動小数点数の乗算を行う代表的な関数は mpfr_mulですが,これはmpfr_mul (x, x, x, rnd)としても全く問題ありません。 この場合は,xの二乗を丸めモードrndの下で計算し,その演算結果をxに書き戻します。


Next: , Previous: MPFR Variable Conventions, Up: MPFR Basics

4.4 丸めモード

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: , Previous: Rounding Modes, Up: MPFR Basics

4.5 特殊な値を表現する浮動小数点数

この節では,MPFR関数が返す特殊な浮動小数点数値(mpfr_t型として表現される)について解説します。ここで,「返す」とは,出力用の引数オブジェクトに格納される演算結果の値のことを意味します。関数の返り値そのものはint型の三種値(-1, 0, 1)なので,混同しないようにして下さい。 複数の値を返す関数(例えばmpfr_sin_cos関数など)はこの規則が複数の値の格納先ごとに適用されます。

MPFRの関数には複数の入力引数を必要とするものがあります。この入力引数一つ分は,MPFR数値からなる入力値集合への対応付けを表わしています。 入力値集合から非数を除くと,この写像が指し示す先は拡張された実数,つまり両端の無限大(\pm\inftyを含む拡張実数集合と見なせます。

入力データが目的の数学関数の定義域内に収まっていれば,関数の返り値は“丸めモード”の節で解説している方式で丸められます (符号付きゼロの場合は後述)。定義域外の場合は,各MPFR関数ごとに本マニュアルの関数の解説(MPFR Interface)通りに処理し,特に言及がなければ本節に述べた一般的なルールで処理されます。

入力データが数学関数の定義域外であっても,正負無限大も含む拡張実数集合に収まっていて,かつ,連続的に拡張できる場合,関数の演算結果は極限値となります。例えば,定義域が(+Inf, 0)のmpfr_hypot関数は+Infを返します。但し,このルールを使っても,mpfr_pow 関数は(1,+Inf)では定義できません。この理由は,1に収束するx_nと,+Infに発散するy_nを組み合わせたx_n,y_nという数列を考えてみれば分かります。この時,x_ny_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: , Previous: Floating-Point Values on Special Numbers, Up: MPFR Basics

4.6 例外

MPFRは,サポートする例外ごとにグローバルフラグ(もしくはスレッドごとのフラグ)を定義しています。フラグは2のべき乗を計算するマクロで,それぞれのフラグと例外を関係づけています。複数のフラグやマスクを一つにまとめても特定できるよう,個別のマクロとのORを取ることで,例外を特定できるようになります。

フラグは,クリアしたり(lowered), 立てたり(raised), Exception Related Functionsに解説してある関数で状態を確認することができます。

サポートする例外の一覧を下記に示します。カッコ内は各例外に関係するマクロを意味します。

更に言うと,これら全てのフラグから成るグループはMPFR_FLAGS_ALLマクロで 表現することができます。MPFRの将来のバージョンで新しいフラグが追加されても, このマクロにはそれが追加される予定です。

ISO C99規格との相違点は下記の通りです。


Next: , Previous: Exceptions, Up: MPFR Basics

4.7 メモリ制御

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

4.8 MPFRからパフォーマンスを引き出す術

ここでは,MPFRのパフォーマンスを生かすヒントを記しておきます。


Next: , Previous: MPFR Basics, Up: Top

5 MPFRの関数

MPFRの多倍長精度浮動小数点関数は,mpfr_t型の引数を取ります。

MPFRの浮動小数点演算関数のインターフェースはGNU MPの関数とよく似た作りになっており,関数名はmpfr_という文字列から始まります。

ユーザは変数ごとに精度桁数を指定する必要があります。計算は格納先の変数の指定精度桁数で行われますので,入力用の変数の精度桁数で計算に要するコスト が決まるわけではありません。

MPFRにおける計算の戦略について説明しましょう。まず,要求された演算を正確に(つまり「無限桁で」)実行し, しかる後に,その結果を出力先の変数の精度桁数に,指定された丸め方式で丸めて収めます。 MPFRの浮動小数点演算関数はIEEE754規格の演算の自然な拡張になっており,異なるワードサイズ,異なるコンパイラ,異なるOS環境であっても,同一の結果を返します。

MPFRには計算結果の有効精度を保証する機能はありません。つまり,ユーザ自身が,より高度なレイヤーの機能を活用するなどして(例えばMPFI(多倍長区間演算ライブラリ)等) 自分で計算結果の有効性を確認しなければなりません。 演算の結果,使用する2変数が数桁程度の有効桁数しかなく,より大きな精度桁数の変数にその結果を格納するとなれば, MPFRは馬鹿正直に格納先の桁数の精度で計算を行います。

Cの標準マクロであるerrnoの値は,エラーの有無に関わらず,MPFR関数やマクロではゼロにセットされています。本マニュアルに記述してある場合を除き,MPFRは,利用している他の関数(libc提供の関数群,メモリ割り当て関数など)と同様,errnoをセットすることはありません。


Next: , Previous: MPFR Interface, Up: MPFR Interface

5.1 初期化関数

mpfr_t型の変数オブジェクトは,値を代入する前に,mpfr_init関数やmpfr_init2関数で初期化しておく必要があります。

— Function: void mpfr_init2 (mpfr_t x, mpfr_prec_t prec)

変数xを初期化します。その際,精度桁数(仮数部の桁数)を正確にprecビットに設定し,値をNaNとします。

[注記] この関数とは違い,GNU MPのMPF初期化関数はゼロを代入します。

通常,変数の初期化は1回だけ行い,mpfr_clear関数を使って消去してから再初期化するようにしましょう。 初期化後の変数に対する精度桁数の変更は,mpfr_set_prec関数を使って行います。 精度桁数precMPFR_PREC_MIN以上,MPFR_PREC_MAX以下の整数として指定します。 この指定に従わない場合の挙動は規定されていませんので注意して下さい。

— Function: void mpfr_inits2 (mpfr_prec_t prec, mpfr_t x, ...)

va_listで指定された全てのmpfr_t型変数を初期化します。精度桁数はprecビットに,値はNaN が代入されます。 詳細はmpfr_init2関数の説明を参照して下さい。 mpfr_t型の変数,もしくはmpft_ptrポインタだけから構成されているva_listが指定できます。 このva_listは変数xから始まり,mpfr_ptr型のNULLポインタで終わります。

— Function: void mpfr_clear (mpfr_t x)

変数xの仮数部が確保している記憶領域を解放します。この関数を使用する際には,該当mpfr_t変数 への処理がすべて完了していることを確認するようにして下さい。

— Function: void mpfr_clears (mpfr_t x, ...)

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);
     }
— Function: void mpfr_init (mpfr_t x)

変数xを初期化し,精度桁数をデフォルト値にセットし,値としてNaN を代入します。 デフォルトの精度桁数はmpfr_set_default_prec関数で変更できます。

[注意] プログラムの実行中,使用している他のライブラリからデフォルト精度桁数を変更され,初期化済みの変数の精度桁数は変更前のままになっているケースが見受けられます。確実に精度桁数を指定したければmpfr_init2関数を使って下さい。

— Function: void mpfr_inits (mpfr_t x, ...)

va_listリストにあるすべてのmpfr_t変数を初期化し,デフォルトの精度桁数をセットし,値としてNaN を代入します。 詳細はmpfr_init関数の説明を参照して下さい。 va_listリストの変数は全てmpfr_t型(もしくは同等のmpfr_ptrポインタ)であると仮定しています。 このリストは変数xから始まり, 最後はmpfr_ptr型のNULLポインタが終端となります。

[注意] プログラムの中で,リンクした他のライブラリからデフォルト精度桁数を変更され,元の変数の精度桁数はそのままにされるということも起こり得ます。確実に精度桁数を設定したければmpfr_inits2関数を使用して下さい。

— Macro: MPFR_DECL_INIT (name, prec)

このマクロはnameという名前で自動的にmpfr_t型の変数を生成し,初期化を行い, 確実に精度桁数をprecビットに設定し,値としてNaN を代入します。nameは有効な変数名でなければなりません。 このマクロは変数宣言部分で使用して下さい。mpfr_init2関数より高速に動作しますが,次のような欠点もあります。

— Function: void mpfr_set_default_prec (mpfr_prec_t prec)

デフォルトの精度桁数をprecビットに設定します。ここで precにはMPFR_PREC_MIN以上, MPFR_PREC_MAX以下の整数が指定できます。 ここで言う変数の精度桁数は,仮数部のビット長を意味します。 この関数の使用以降に呼び出されるmpfr_init関数やmpfr_inits関数は 設定後の精度桁数を変数にセットしますが,それ以前に初期化された変数の精度桁数は変更されません。 精度桁数の初期値は53ビットです。

[注意] MPFRを‘--enable-thread-safe’オプション設定してビルドすると,デフォルトの精度桁数は 各スレッドごとに設定されたものになります。詳細はSee Memory Handlingを参照して下さい。

— Function: mpfr_prec_t mpfr_get_default_prec (void)

現在の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つの関数は,計算の途中で精度桁数$2変更したい場合に有用です。 よくある例としては,Newton-Raphson法のような反復法において,解の近似度に応じて精度桁数を適宜調整する際に役立ちます。

— Function: void mpfr_set_prec (mpfr_t x, mpfr_prec_t prec)

変数xの精度桁数をprecビットに設定し直し,NaN を代入します。 変数xに入っていた値はNaN に上書きされます。この関数の機能としては,mpfr_clear(x)で変数を消去した後に mpfr_init2(x, prec)で初期化した場合と同じですが,xの仮数部長が,設定後の精度桁数が十分格納できるものであれば,メモリ領域の再確保を行わない分,高速に実行できます。 精度桁数precMPFR_PREC_MIN以上, MPFR_PREC_MAX以下の任意の整数を設定できます。 変数xに格納されている値を保存しておきたい場合は,mpfr_prec_round関数を利用して下さい。

[注意] 変数xMPFR_DECL_INITマクロや,mpfr_custom_init_set(see Custom Interface)関数で初期化されている場合は,この関数は使用できません。

— Function: mpfr_prec_t mpfr_get_prec (mpfr_t x)

変数xの精度桁数,つまり,仮数部のビット長を返します。


Next: , Previous: Initialization Functions, Up: MPFR Interface

5.2 代入関数

この節で解説する関数は,初期化済み(see Initialization Functions)の浮動小数点変数に新しい値を代入するためのものです。

— Function: int mpfr_set (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_set_ui (mpfr_t rop, unsigned long int op, mpfr_rnd_t rnd)
— Function: int mpfr_set_si (mpfr_t rop, long int op, mpfr_rnd_t rnd)
— Function: int mpfr_set_uj (mpfr_t rop, uintmax_t op, mpfr_rnd_t rnd)
— Function: int mpfr_set_sj (mpfr_t rop, intmax_t op, mpfr_rnd_t rnd)
— Function: int mpfr_set_flt (mpfr_t rop, float op, mpfr_rnd_t rnd)
— Function: int mpfr_set_d (mpfr_t rop, double op, mpfr_rnd_t rnd)
— Function: int mpfr_set_ld (mpfr_t rop, long double op, mpfr_rnd_t rnd)
— Function: int mpfr_set_float128 (mpfr_t rop, __float128 op, mpfr_rnd_t rnd)
— Function: int mpfr_set_decimal64 (mpfr_t rop, _Decimal64 op, mpfr_rnd_t rnd)
— Function: int mpfr_set_z (mpfr_t rop, mpz_t op, mpfr_rnd_t rnd)
— Function: int mpfr_set_q (mpfr_t rop, mpq_t op, mpfr_rnd_t rnd)
— Function: int mpfr_set_f (mpfr_t rop, mpf_t op, mpfr_rnd_t rnd)

これらの関数群は,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に渡されてしまいます。

— Function: int mpfr_set_ui_2exp (mpfr_t rop, unsigned long int op, mpfr_exp_t e, mpfr_rnd_t rnd)
— Function: int mpfr_set_si_2exp (mpfr_t rop, long int op, mpfr_exp_t e, mpfr_rnd_t rnd)
— Function: int mpfr_set_uj_2exp (mpfr_t rop, uintmax_t op, intmax_t e, mpfr_rnd_t rnd)
— Function: int mpfr_set_sj_2exp (mpfr_t rop, intmax_t op, intmax_t e, mpfr_rnd_t rnd)
— Function: int mpfr_set_z_2exp (mpfr_t rop, mpz_t op, mpfr_exp_t e, mpfr_rnd_t rnd)

opに2のe乗を掛けたものを丸め方式rndで丸めてropに代入します。 入力値が0の場合は+0に変換されます。

— Function: int mpfr_set_str (mpfr_t rop, const char *s, int base, mpfr_rnd_t rnd)

rop進数表現として文字列sを解釈し,丸め方式rndで丸めた値をropに代入します。 有効な文字列形式の詳細についてはmpfr_strtofr関数の説明を読んで下さい。 mpfr_strtofr関数とは異なり,mpfr_set_str関数は,完全に浮動小数点数として解釈できる文字列だけを扱います。

返り値の意味は,他のMPFR関数とは異なりますので注意して下さい。 最後のNULL終端まで完璧なbase進表現の浮動小数点数になっていれば0を返し,そうでない場合は,ropの値は書き換えられ,−1を返します。(3種の返り値ternary valueが必要であれば,mpfr_strtofr関数を使って下さい。)

[注意] ropが無限大になった時,それが無限大のsを入力したせいなのか,オーバーフローしたせいなのかを 見分けたい場合はmpfr_strtofr関数を使って下さい。

— Function: int mpfr_strtofr (mpfr_t rop, const char *nptr, char **endptr, int base, mpfr_rnd_t rnd)

base進表現の文字列nptrを読み取り,丸め方式rndで丸めて返します。 baseは 0 (これも下記に示すように有効な進数です)か,2以上62以下の整数でなければ なりません。これ以外の指定をした場合の挙動は未確定です。 nptrが有効なデータ形式から始まっていれば,値はropに代入され,*endptrは, これがNULLポインタでなければ,有効な文字列データの終端文字を指します。 もしNULLポインタであれば,ropにはゼロが代入されます(strtod関数の処理に準じています)。 nptrの値は,endptrがNULLポインタでなければ,これが指しているメモリ領域に格納されます 返り値は3種の値(-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を表現しています。

— Function: void mpfr_set_nan (mpfr_t x)
— Function: void mpfr_set_inf (mpfr_t x, int sign)
— Function: void mpfr_set_zero (mpfr_t x, int sign)

それぞれ,変数xにNaN (非数), 無限大,ゼロを代入します。 mpfr_set_inf関数やmpfr_set_zero関数は,signが非負であれば,xにプラス無限大とプラスゼロを代入します。 mpfr_set_nan関数の場合は,符号ビットは不確定となります。

— Function: void mpfr_swap (mpfr_t x, mpfr_t y)

変数xと変数yが指している構造体を入れ替えます。値が丸められることはありません。 この点,3番目の引数で丸めモードを指定する3つのmpfr_set関数グループとは挙動が異なります。

[注意] 精度桁数が入れ替わると,その後の代入処理に影響が出てくる恐れがあります。 また,仮数部のポインタも入れ替わりますので,xyにそれを許容しない 割り当て方をした場合は,この関数を使わないようにして下さい。xyが,MPFR_DECL_INITマクロやmpfr_custom_init_set (see Custom Interface) で確保されたものである場合が相当します。


Next: , Previous: Assignment Functions, Up: MPFR Interface

5.3 初期化代入関数

— Macro: int mpfr_init_set (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_ui (mpfr_t rop, unsigned long int op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_si (mpfr_t rop, long int op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_d (mpfr_t rop, double op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_ld (mpfr_t rop, long double op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_z (mpfr_t rop, mpz_t op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_q (mpfr_t rop, mpq_t op, mpfr_rnd_t rnd)
— Macro: int mpfr_init_set_f (mpfr_t rop, mpf_t op, mpfr_rnd_t rnd)

変数ropを初期化し,丸め方式rndで丸めたopを代入します。 ropの精度桁数は,mpfr_set_default_prec関数で設定した現状のデフォルト値が設定されます。

— Function: int mpfr_init_set_str (mpfr_t x, const char *s, int base, mpfr_rnd_t rnd)

xを初期化し,base進表現の文字列sを丸め方式rndで丸めて代入します。 詳細はmpfr_set_str関数の説明を参照して下さい。


Next: , Previous: Combined Initialization and Assignment Functions, Up: MPFR Interface

5.4 データ型変換関数

— Function: float mpfr_get_flt (mpfr_t op, mpfr_rnd_t rnd)
— Function: double mpfr_get_d (mpfr_t op, mpfr_rnd_t rnd)
— Function: long double mpfr_get_ld (mpfr_t op, mpfr_rnd_t rnd)
— Function: __float128 mpfr_get_float128 (mpfr_t op, mpfr_rnd_t rnd)
— Function: _Decimal64 mpfr_get_decimal64 (mpfr_t op, mpfr_rnd_t rnd)

変数opの値を丸め方式rndで丸めて,floatdouble, 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関数の説明文を参照して下さい。

— Function: long mpfr_get_si (mpfr_t op, mpfr_rnd_t rnd)
— Function: unsigned long mpfr_get_ui (mpfr_t op, mpfr_rnd_t rnd)
— Function: intmax_t mpfr_get_sj (mpfr_t op, mpfr_rnd_t rnd)
— Function: uintmax_t mpfr_get_uj (mpfr_t op, mpfr_rnd_t rnd)

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関数の説明も参照して下さい。

— Function: double mpfr_get_d_2exp (long *exp, mpfr_t op, mpfr_rnd_t rnd)
— Function: long double mpfr_get_ld_2exp (long *exp, mpfr_t op, mpfr_rnd_t rnd)

返り値として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は不定値となります。

— Function: int mpfr_frexp (mpfr_exp_t *exp, mpfr_t y, mpfr_t x, mpfr_rnd_t rnd)

exp(形式的にはexpへのポインタ)とyを, 0.5<=abs(y)<1,かつ,y に2のexp乗を掛けたものが, xyの精度桁数にrnd方向に丸めたものと等しくなるように値を代入します。 xがゼロの時は,yにも同じ符号が付加されて, expはゼロになります。 xがNaNもしくは無限大の場合は同じ値がyに代入され,expの値は不定になります。

— Function: mpfr_exp_t mpfr_get_z_2exp (mpz_t rop, mpfr_t op)

opの仮数部をスケールし,opの精度桁数の整数としてropに代入し, 指数部expを返り値とします。この際,現状の指数部の範囲を超えたものになる可能性があります。 つまり,oprop に2のexp乗を掛けたもの. と等しい値になります。 opがゼロであれば, 指数部の最小値eminが返されます。 opがNaNもしくは無限大であれば,範囲エラーフラグがセットされ, ropには0が入り, 指数部の最小値eminが返されます。 返り値の指数部は,実行時におけるMPFRの最小指数部より小さい値になる可能性があります。 指数部がmpfr_exp_t型として表現できない値になる場合は,範囲エラーフラグがセットされ, mpfr_exp_t型で表現できる最小値が返されます。

— Function: int mpfr_get_z (mpz_t rop, mpfr_t op, mpfr_rnd_t rnd)

opを,rnd方向に丸めた後,mpz_t型に変換します。 opがNaNもしくは無限大の時は,範囲エラーフラグを立て, ropに0を代入し, 0を返します。それ以外の時は,ropopと等しい時(つまり,op が整数の時)はゼロを返し,opより大きくなる時は正の値を,opより小さくなる時は 負の値を返します。また,ropopと異なる時,つまり,opが整数でない時は, 不正確フラグを立てます。

— Function: void mpfr_get_q (mpq_t rop, mpfr_t op)

opを変換しmpq_tに格納します。 opがNaN,もしくは無限大の時は,範囲エラーフラグがセットされ, ropにはゼロが代入されます。それ以外の場合は,常に正確な変換が行われます。

— Function: int mpfr_get_f (mpf_t rop, mpfr_t op, mpfr_rnd_t rnd)

oprnd方向に丸めてmpf_t型に変換します。 opがNaNもしくは無限大の時は,これに相当するものはMPFには存在しないので,範囲エラーフラグを立てます。 opがNaNの時はropの値は不定になります。 opが+Inf (−Inf)の時は,ropはMPF型変数の精度桁数における最大値(最小値)になります。 将来MPFが無限大をサポートするようになれば,このような動作は正しくないので,手直しされることでしょう (ポータブルなプログラムを目指すのであれば,ropには有限の値か,無限大が代入されるようにすべきです)。 現状,MPFRの指数部はMPFと同じデータ型なので(基数は異なりますが),指数部の範囲はMPFの方がMPFRより大きくなります。 従って,オーバーフローやアンダーフローの対応付けはできません。

— Function: char * mpfr_get_str (char *str, mpfr_exp_t *expptr, int b, size_t n, mpfr_t op, mpfr_rnd_t rnd)

opを基数bの文字列として,丸めモードrndで丸めて変換します。 ここでnはゼロ(下記参照),もしくは文字列として出力される有効桁数を意味します。 後者の意味の場合は,nは2以上でなければなりません。 基数として使用できるのは2以上62以下の自然数で,これ以外の値を基数として指定すると,この関数は 何も処理を行わず,NULLポインタを返します。

入力値が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のべき乗の場合はpp−1に置き換えて下さい。 但し,レアケースですが,m+1桁になる場合もあります。基数が62以下の最小の事例としては, 基数が7と49で,pが186564318007の時がそれにあたります。

strがNULLポインタの時も,仮数部用の文字列メモリ領域はメモリ割り当て関数(see Memory Handling) で確保され,基数が無効な値でなければ,その文字列へのポインタが返り値となります。この場合,返されたポインタが指す 文字列を解放するためには必ずmpfr_free_str関数を使って下さい。

strがNULLポインタでなければ, ポインタが指すメモリ領域が仮数部を格納する十分な 大きさが確保されていなければなりません。どんな値に対しても安全なサイズは,nがゼロでない場合は max(n + 2, 7)nがゼロの場合は,前述の説明の通りm+1確保しておく必要があります。 2バイト分余計に確保するのは,終端子用のNULL文字に加えて,マイナス符号が付加される可能性があるからです。 最低でも7バイト確保する理由は,‘-@Inf@’をNULL終端子含めて表現するためです。 基数が無効な値でない限り,文字列strへのポインタが返り値となります。

他の関数同様,変換された文字列が丸められて誤差を含む時には,不正確フラグを立てます。

— Function: void mpfr_free_str (char *str)

mpfr_get_str関数で割り当てられた文字列を,メモリ解放関数(see Memory Handling) で解放します。 このメモリブロックはstrlen(str)+1バイト確保されているものと想定されています。

— Function: int mpfr_fits_ulong_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_slong_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_uint_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_sint_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_ushort_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_sshort_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_uintmax_p (mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_fits_intmax_p (mpfr_t op, mpfr_rnd_t rnd)

oprnd方向に丸めた結果が,それぞれ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: , Previous: Conversion Functions, Up: MPFR Interface

5.5 基本演算関数

— Function: int mpfr_add (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_add_ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_add_si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_add_d (mpfr_t rop, mpfr_t op1, double op2, mpfr_rnd_t rnd)
— Function: int mpfr_add_z (mpfr_t rop, mpfr_t op1, mpz_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_add_q (mpfr_t rop, mpfr_t op1, mpq_t op2, mpfr_rnd_t rnd)

op1 + op2を求めてrnd方向に丸め,ropに代入します。 符号付きゼロの場合はIEEE 754のルールが適用されます。 符号なしゼロの場合も,0は符号付きとして処理されます。つまり(+0) + 0 = (+0)や,(−0) + 0 = (−0))となります。 mpfr_add_d関数においては,double型は基数が2のべき乗,精度桁数はCの実装値(IEEE_DBL_MANT_DIGマクロ定義値,なければ53ビット)として処理を行います。

— Function: int mpfr_sub (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_ui_sub (mpfr_t rop, unsigned long int op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_sub_ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_si_sub (mpfr_t rop, long int op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_sub_si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_d_sub (mpfr_t rop, double op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_sub_d (mpfr_t rop, mpfr_t op1, double op2, mpfr_rnd_t rnd)
— Function: int mpfr_z_sub (mpfr_t rop, mpz_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_sub_z (mpfr_t rop, mpfr_t op1, mpz_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_sub_q (mpfr_t rop, mpfr_t op1, mpq_t op2, mpfr_rnd_t rnd)

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関数に対しても,より厳格に適用されています。

— Function: int mpfr_mul (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_d (mpfr_t rop, mpfr_t op1, double op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_z (mpfr_t rop, mpfr_t op1, mpz_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_q (mpfr_t rop, mpfr_t op1, mpq_t op2, mpfr_rnd_t rnd)

op1 times op2を計算し,丸めモードrndで丸めてropに格納します。 計算結果がゼロになる時の符号は,二数の符号の積で決定されます。符号なしゼロはプラス符号と判断します。 mpfr_add_d関数と同様の制限がmpfr_mul_dにも課されます。

— Function: int mpfr_sqr (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opの2乗を計算し,rnd方式で丸めてropに代入します。

— Function: int mpfr_div (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_ui_div (mpfr_t rop, unsigned long int op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_si_div (mpfr_t rop, long int op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_d_div (mpfr_t rop, double op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_d (mpfr_t rop, mpfr_t op1, double op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_z (mpfr_t rop, mpfr_t op1, mpz_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_q (mpfr_t rop, mpfr_t op1, mpq_t op2, mpfr_rnd_t rnd)

op1/op2を求め,丸め方式rndで丸めてropに代入します。 演算結果がゼロの時は,2数の符号の積で符号が決定されます。 符号なしゼロの時は,プラス0として扱います。 op1が非零で,op2がゼロの時,演算結果は今のところ ±Infですが,将来的にはNaNになるかもしれません。IEEE 754で正反対の決定をしなければ,ですが。 mpfr_add_d関数における制限事項は,mpfr_d_div関数にも, mpfr_div_d関数にも適用されます。

— Function: int mpfr_sqrt (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_sqrt_ui (mpfr_t rop, unsigned long int op, mpfr_rnd_t rnd)

opの平方根を求め,rnd方式で丸めてropに代入します。 opが−0の時は,IEEE754規格の定めに従って処理します。 opが負の時は,ropにはNaNが代入されます。

— Function: int mpfr_rec_sqrt (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opの平方根の逆数を計算し,rnd方向に丸めてropに代入します。 opが is ±0の時はropには+Infが,opが+0の時は+Infが, opが負数の時はNaNが,それぞれ代入されます。

[注意] −0に対する値は+Infで,IEEE 754-2008 規格(9.2.1節)で推奨されているrSqrt関数の値である-Infではありません。

— Function: int mpfr_cbrt (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_rootn_ui (mpfr_t rop, mpfr_t op, unsigned long int k, mpfr_rnd_t rnd)

opの平方根(k乗根)を計算し,rnd方式で丸めてropに代入します。 k = 0の場合は,ropにNaNを代入します。 kが奇数(偶数)で,opが(−Infも含む)負数である時, ropには,kのゼロではない)値に関わらず,負数(NaN)が代入されます。 opがゼロの時は,ropには通常の極限値ルールに則った符号付けがなされたゼロが代入されます。 つまり, kが奇数の時はopと同じ符号になり,偶数の時はプラス符号が付きます。

これらの関数は,IEEE 754-2008規格(9.2節)のrootn関数の処理に則った動作を行います。

— Function: int mpfr_root (mpfr_t rop, mpfr_t op, unsigned long int k, mpfr_rnd_t rnd)

この関数はmpfr_rootn_ui関数と同じ機能を持ちます。但し,op が−0でkが偶数の時は,+0ではなく−0を返すところが異なります。 これはmpfr_sqrt関数と齟齬が出ないようにするための措置です。 opがゼロの時は,ropopの値をそのまま代入します。

この関数はIEEE 754-2008規格が固まる前に作られたものなので,規格が定めたrootn関数とは動作が 多少異なります。将来のバージョンで廃止予定の関数です。

— Function: int mpfr_pow (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_pow_ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_pow_si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_pow_z (mpfr_t rop, mpfr_t op1, mpz_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_ui_pow_ui (mpfr_t rop, unsigned long int op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_ui_pow (mpfr_t rop, unsigned long int op1, mpfr_t op2, mpfr_rnd_t rnd)

op1op2乗を計算し,rnd方式で丸めてropに代入します。 特殊値に対しては,ISO C99及びIEEE 754-2008規格が定めるpow関数に準じた振る舞いをします。

[注記] 整数型の0は,上記の関数では+0と扱います。 この場合,pow関数と同様,通常の極限値としては考えません。

— Function: int mpfr_neg (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_abs (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

それぞれ,-opopの絶対値を,rnd方式で丸めてropに代入します。 ropopが同じ変数である時には,符号を必要に応じて変更し,異なる変数であれば,rop の精度桁数がopより小さい時には丸め処理が実施されます。

このような符号処理の方式は,IEEE 754のnegate関数とabs関数を真似して,NaNに対しても行われます。 つまり,mpfr_neg関数は符号を反転し,mpfr_abs関数は符号を正にします。 但し,IEEE 754とは違って,通常NaNフラグは立てます。

— Function: int mpfr_dim (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

op1op2の正定値(positive difference)を計算し,rnd方式で丸めてropに代入します。 つまり,op1 > op2の場合はop1 - op2を求め, op1 <= op2の時は+0を代入し,op1もしくはop2がNaNの時はNaNを代入します。

— Function: int mpfr_mul_2ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_mul_2si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)

op1に2のop2乗を掛けたものを計算し,rnd方式で丸めてropに代入します。 ropop1が同一の変数である場合は,2のop2乗分増えていきます。

— Function: int mpfr_div_2ui (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_2si (mpfr_t rop, mpfr_t op1, long int op2, mpfr_rnd_t rnd)

op1を2のop2で割ったものを求め,rnd方式で丸めてropに代入します。 ropop1が同一の変数である場合は,2のop2乗分減っていきます。


Next: , Previous: Basic Arithmetic Functions, Up: MPFR Interface

5.6 比較関数

— Function: int mpfr_cmp (mpfr_t op1, mpfr_t op2)
— Function: int mpfr_cmp_ui (mpfr_t op1, unsigned long int op2)
— Function: int mpfr_cmp_si (mpfr_t op1, long int op2)
— Function: int mpfr_cmp_d (mpfr_t op1, double op2)
— Function: int mpfr_cmp_ld (mpfr_t op1, long double op2)
— Function: int mpfr_cmp_z (mpfr_t op1, mpz_t op2)
— Function: int mpfr_cmp_q (mpfr_t op1, mpq_t op2)
— Function: int mpfr_cmp_f (mpfr_t op1, mpf_t op2)

op1op2を比較します。op1 > op2の時は正の値を, op1 = op2の時はゼロを,op1 < op2の時は負数を返します。 op1op2がどちらも同じ精度桁数フルで値が入っている場合は,差を取って判断します。 どちらかの値がNaNの時は,範囲エラーフラグが立てられて,ゼロを返します。

[注記] この比較関数は3種類のケースを見分けることができます。できています。2種類だけを見分けたい 場合は,後述するように,先読み関数(例えばmpfr_equal_p関数は2数が等しいかどうか判断できます)を使って下さい。 比較される値にNaNがある場合は,IEEE 754規格の比較と同じ振る舞いをします。比較は浮動小数点数のみ対象なので,必要に応じて データ変換も行われます。

— Function: int mpfr_cmp_ui_2exp (mpfr_t op1, unsigned long int op2, mpfr_exp_t e)
— Function: int mpfr_cmp_si_2exp (mpfr_t op1, long int op2, mpfr_exp_t e)

op1op2に2のe乗を掛けたものを比較します。 返り値は上記の関数と同じです。

— Function: int mpfr_cmpabs (mpfr_t op1, mpfr_t op2)

|op1|と|op2|を比較します。 |op1| > |op2|の時は正の値を,|op1| = |op2|の時はゼロを, |op1| < |op2|の時は負の値を返します。 比較対象の値にNaNがある場合は,範囲エラーフラグを立ててゼロを返します。

— Function: int mpfr_nan_p (mpfr_t op)
— Function: int mpfr_inf_p (mpfr_t op)
— Function: int mpfr_number_p (mpfr_t op)
— Function: int mpfr_zero_p (mpfr_t op)
— Function: int mpfr_regular_p (mpfr_t op)

opがそれぞれNaN,無限大,NaNでも無限大でもない浮動小数点数,ゼロ,NaNでも無限大でもゼロでもない浮動小数点数である場合は,非ゼロ数を返します。それ以外の場合はゼロを返します。

— Macro: int mpfr_sgn (mpfr_t op)

op > 0の時は正の値を,op = 0の時はゼロを, op < 0の時は負の値を返します。 引数がNaNの場合は,範囲エラーフラグを立ててゼロを返します。 mpfr_cmp_ui (op, 0)と同じ働きをしますが,このマクロの方が高速に実行できます。

— Function: int mpfr_greater_p (mpfr_t op1, mpfr_t op2)
— Function: int mpfr_greaterequal_p (mpfr_t op1, mpfr_t op2)
— Function: int mpfr_less_p (mpfr_t op1, mpfr_t op2)
— Function: int mpfr_lessequal_p (mpfr_t op1, mpfr_t op2)
— Function: int mpfr_equal_p (mpfr_t op1, mpfr_t op2)

それぞれ op1 > op2, op1 >= op2, op1 < op2, op1 <= op2, op1 = op2の場合は非ゼロ数を, それ以外の場合はゼロを返します。 op1op2の一つ以上がNaNであれば,必ずゼロを返します。

— Function: int mpfr_lessgreater_p (mpfr_t op1, mpfr_t op2)

op1 < op2もしくは op1 > op2であれば非ゼロを返します。これはop1op2も NaNではなく,op1 <> op2である場合と同等です。それ以外の場合,つまりop1op2にNaNがある場合,もしくはop1 = op2であれば,ゼロを返します。

— Function: int mpfr_unordered_p (mpfr_t op1, mpfr_t op2)

op1もしくはop2がNaNであれば,つまり両者の比較ができない場合は非ゼロを返します。それ以外の場合はゼロを返します。


Next: , Previous: Comparison Functions, Up: MPFR Interface

5.7 初等関数・特殊関数

一部の例外(mpfr_sin_cos関数など)を除き,ここで述べている全ての関数の返り値は3つの値ternary valueを返します。丸めなしの真値を返す場合は0を,真値より大きい値を返す場合は正の値を,それ以外の場合は負の値を返します。

[重要] 引数がある領域にある場合,要求精度桁数が小さくても,初等関数や特殊関数の計算(ことに,正確な丸め処理を行うため)に時間がかかることがあります。例えば三角関数やベッセル関数の引数が大きい場合がそれにあたります。 他にも,関数によっては,メモリの使用量が必ずしも出力する値の精度桁数に依存しないこともあります。mpfr_rootn_ui関数は引数kの大きさに比例し,不完全ガンマ関数は引数opに比例してメモリ使用量が増えます。

— Function: int mpfr_log (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_log_ui (mpfr_t rop, unsigned long op, mpfr_rnd_t rnd)
— Function: int mpfr_log2 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_log10 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

上から順に,opの自然対数,log2(op), log10(op)を計算し,丸め方式rndで丸めてropに代入します。 丸め方式に関わらず,opが1の時は,ropは+0になります。これはISO C99規格とIEEE 754-2008標準規格に基づいたものです。 opが±0の時,即ち,ゼロの符号が結果に何ら影響がない場合は,ropには−Infが代入されます。

— Function: int mpfr_log1p (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

op+1の自然対数の計算を行い,丸め方式rndで丸めてropに格納します。 opが−1の時は,ropには−Infが代入されます。

— Function: int mpfr_exp (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_exp2 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_exp10 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

この二つの関数は,それぞれopの2のべき乗,もしくは 10のべき乗を計算し,丸めモードrndで丸め,ropに代入します。

— Function: int mpfr_expm1 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

exp(op)から1を引いた値を求め,丸めモードrndで丸め,ropに代入します。

— Function: int mpfr_cos (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_sin (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_tan (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

それぞれ三角関数sin(op), cos(op), tan(op)の値を求め,rnd方向に丸め, ropに代入します。

— Function: int mpfr_sin_cos (mpfr_t sop, mpfr_t cop, mpfr_t op, mpfr_rnd_t rnd)

sopにはsin(op)の値を,copにはcos(op)の値を,sop, copの精度桁数に収まるよう,それぞれrnd方向に丸めて同時に代入します。sopcopは異なる変数でなければなりません。 両方の値が丸めなしで収まる時は0を返します。より正確に言うと,返り値はs+4cという式で表現され,sopが丸めなしの場合はs=0となり, 丸めた近似値が大きくなる時はs=1,小さくなる時はs=2となります。cの値も,copの丸めた結果に応じてs同様に決まります。

— Function: int mpfr_sec (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_csc (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_cot (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

sec(op), cosec(op), cot(op)の値を求め,rnd方式で丸めてropに代入します。

— Function: int mpfr_acos (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_asin (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_atan (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

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の精度桁数が少ない時,等についても同様のことが言えます。

— Function: int mpfr_atan2 (mpfr_t rop, mpfr_t y, mpfr_t x, mpfr_rnd_t rnd)

アークタンジェント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関数同様,次のように値が決まります。

— Function: int mpfr_cosh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_sinh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_tanh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

双曲線関数の値,cosh(op), sinh(op),tanh(op)の値を求め,rnd方式で丸めてropに代入します。

— Function: int mpfr_sinh_cosh (mpfr_t sop, mpfr_t cop, mpfr_t op, mpfr_rnd_t rnd)

双曲線関数sinh(op)とcosh(op)の値を同時に求め,それぞれsopcopの精度桁数に収まるようにrnd方式で丸めて代入します。この時,sopcopは必ずそれぞれ異なる変数を指定して下さい。 両方の出力値が丸めなしで正しい値になる場合のみ0を返します。返り値の詳細についてはmpfr_sin_cos関数の説明を参照して下さい。

— Function: int mpfr_sech (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_csch (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_coth (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

双曲線関数,sech(op),cosech(op),coth(op)の値を求め,rnd方式で丸めてropに代入します。

— Function: int mpfr_acosh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_asinh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_atanh (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

逆双曲線関数,arccosh(op),arcsinh(op),arctanh(op)の値をそれぞれ求めて,rnd方式で丸めてropに代入します。

— Function: int mpfr_fac_ui (mpfr_t rop, unsigned long int op, mpfr_rnd_t rnd)

opの階乗を求め,rnd方式で丸めてropに代入します。

— Function: int mpfr_eint (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

指数積分値 を求め,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式を参照)。

— Function: int mpfr_li2 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

多重対数関数Li2(op)の値を求め,rnd方式で丸めてropに代入します。 MPFRではという定義を多重対数関数として採用しています。

— Function: int mpfr_gamma (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_gamma_inc (mpfr_t rop, mpfr_t op, mpfr_t op2, mpfr_rnd_t rnd)

opのガンマ関数とopop2の不完全ガンマ関数の値を計算し,rnd方式で丸めてropに代入します。このマニュアルではmpfr_gamma_incを不完全ガンマ関数(incomplete Gamma function)と呼びますが,補不完全ガンマ関数(complementary incomplete Gamma function)と呼ぶこともあります。 mpfr_gamma関数と,op2がゼロの時のmpfr_gamma_inc関数は,opが負の整数の時,ropにNaNを代入します。

[注記] 現状のmpfr_gamma_inc関数は,ropopが大きい場合は低速になってしまう問題があります。また,時によっては内部の計算でオーバーフローが発生することがあります。

— Function: int mpfr_lngamma (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opの対数ガンマ関数の値を求め,rnd方式で丸めてropに代入します。 opが1ないし2の時は,丸めモードに関わらずropは+0になります。 opが無限大,もしくは正でない整数の時は,ropは+Infになります。 このあたりの特殊な引数に対する対応は一般的なルールに従っています。 −2k−1 < op < −2kの時は, kが非負の整数であれば,ropはNaNになります。 mpfr_lgamma関数の解説も参照して下さい。

— Function: int mpfr_lgamma (mpfr_t rop, int *signp, mpfr_t op, mpfr_rnd_t rnd)

opのガンマ関数の値の絶対値の対数を求め,rnd方式に丸めてropに代入します。 opのガンマ関数 の値の符号は1 か −1として表現され,signpポインタが指す先に格納されています。 opが1ないし2の時は,丸めモードに関わらずropは+0になります。 opが無限大,もしくは非正の整数であれば,ropは+Infになります。 opがNaN, −Inf,負の整数のいずれかであれば,*signpの指す値は不定値となります。 opが±0の時は,*signpの指す値はゼロの符号を意味するものになります。

— Function: int mpfr_digamma (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opのディガンマ関数(プサイ関数とも呼ばれる)の値を求め,rnd方式で丸め,ropに代入します。 opが負の整数の場合は,ropはNaNになります。

— Function: int mpfr_beta (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

引数が op1op2のベータ関数の値を求め,ropに代入します。

[注記] 現時点の実装では内部でオーバーフローやアンダーフローが起きるケースについて何ら対処を行っていませんので,超高精度な値を内部で使うとトラブるかもしれません。

— Function: int mpfr_zeta (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_zeta_ui (mpfr_t rop, unsigned long op, mpfr_rnd_t rnd)

opのリーマン・ゼータ関数の値を求め,rnd方式で丸め,ropに代入します。

— Function: int mpfr_erf (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_erfc (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opの誤差関数および相補誤差関数の値を求め,rnd方向に丸めて,ropに代入します。

— Function: int mpfr_j0 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_j1 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_jn (mpfr_t rop, long n, mpfr_t op, mpfr_rnd_t rnd)

opの0, 1, n次の第1種ベッセル関数の値を求め,rnd方式で丸めてropに代入します。 opがNaN場合は,ropは常にNaNになります。opが+Infもしくは-Infの時は ropは+0になります。ropが+0でかつnが非ゼロの時は,nの偶奇や符号によってropの値は+0もしくは−0になります。

— Function: int mpfr_y0 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_y1 (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_yn (mpfr_t rop, long n, mpfr_t op, mpfr_rnd_t rnd)

opの0, 1, n次の第2種ベッセル関数の値を求め,rnd方式で丸めてropに代入します。 opがNaNもしくは負の場合は,ropは常にNaNになります。opが+Infの時は ropは+0になります。,opがゼロの時は,nの偶奇や符号によってropの値は+Infもしくは−Infになります。

— Function: int mpfr_fma (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_t op3, mpfr_rnd_t rnd)
— Function: int mpfr_fms (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_t op3, mpfr_rnd_t rnd)

(op1 times op2) + op3や, (op1 times op2) - op3の値を求め,rnd方式で丸め,ropに代入します。特別な値(符号付きゼロ,無限大,NaN)がこの中に入っている場合,加減算の後に行う乗算の流儀に従って値が決定します。つまり,複合演算としての意味は丸め処理だけになります。

— Function: int mpfr_fmma (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_t op3, mpfr_t op4, mpfr_rnd_t rnd)
— Function: int mpfr_fmms (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_t op3, mpfr_t op4, mpfr_rnd_t rnd)

(op1 times op2) + (op3 times op4)や (op1 times op2) - (op3 times op4)の値を求め, rnd方式で丸めてropに代入します。 op1 times op2op3 times op4の計算でオーバーフローやアンダーフローが発生した場合は,この両者を繋ぐ乗算によってropの値が決まります。

— Function: int mpfr_agm (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

op1op2の算術幾何平均を求め,rnd方式で丸め,ropに代入します。 算術幾何平均とは,数列u_nv_nの共通の極限値で, u_0=op1, v_0=op2という初期値から出発し, u_(n+1)はu_nv_nの算術平均, v_(n+1)はu_nv_nの幾何平均として計算したものです。 op1op2のどちらも負か,片方が非負である時は,ropはNaNになります。 op1op2のどちらもゼロか,片方が有限値(無限大)の時は,ropは+0 (NaN)になります。

— Function: int mpfr_hypot (mpfr_t rop, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)

xyのユークリッドノルム,即ち xyの2乗和の平方根 を求め,rnd方式で丸めてropに代入します。 特殊値の場合はISO C99 (F.9.4.3節)および IEEE 754-2008 (9.2.1節)に述べられている通りに処理されます。 つまり, xもしくはyが無限大の時は,+Infがropに代入され,それ以外の特殊値の場合はNaNが代入されます。

— Function: int mpfr_ai (mpfr_t rop, mpfr_t x, mpfr_rnd_t rnd)

アーリー関数Ai(x)の値を求め,rnd方式で丸め,ropに代入します。 xが NaNの時は, ropは常にNaNになります。xが+Infもしくは−Infの時は, ropは+0になります。 現状の実装では,引数が大きな値になることが想定されておらず, abs(x)は500より十分小さい値でないとうまく計算できません。大きな引数になる場合は 他の方法を使用するか,未来のバージョンの登場をお待ち下さい。

— Function: int mpfr_const_log2 (mpfr_t rop, mpfr_rnd_t rnd)
— Function: int mpfr_const_pi (mpfr_t rop, mpfr_rnd_t rnd)
— Function: int mpfr_const_euler (mpfr_t rop, mpfr_rnd_t rnd)
— Function: int mpfr_const_catalan (mpfr_t rop, mpfr_rnd_t rnd)

ropに,2の自然対数,Pi, オイラー定数0.577...,カタラン定数0.915...をそれぞれrnd方式で丸めて代入します。 一度これらの値がキャッシュされると,これと同じか,より低い精度桁数の値の要求があっても再計算を行いません。 キャッシュをクリアするには,mpfr_free_cache関数かmpfr_free_cache2関数を使って下さい。

— Function: void mpfr_free_cache (void)

MPFRの内部で使用される,キャッシュやプールを全て消去します。スレッドローカルのものや,全てのスレッドで共有されているものが対象となります。 明示的にmpfr_const_*関数を呼び出していなくても,MPFRの内部で利用していることがあるので, スレッドを停止させる前にはこの関数を呼び出すようにして下さい。

— Function: void mpfr_free_cache2 (mpfr_free_cache_t way)

MPFRの内部で使用しているキャッシュやプールをwayのフラグ値で指定した方法で消去します。 このフラグの設定には以下のものが使えます。

上記以外のwayに立っているフラグは現状では無視されます。将来は使用するかもしれませんので,その他のフラグは立てずにゼロにしておくようにしましょう。

[注記] mpfr_free_cache2(MPFR_FREE_LOCAL_CACHE|MPFR_FREE_GLOBAL_CACHE)は 今のところ,mpfr_free_cache()と同じ働きをします。

— Function: void mpfr_free_pool (void)

MPFRの内部で使用されているプールを消去します。

[注記] この関数は,mpfr_free_cache関数やmpfr_free_cache2関数でスレッドローカルなキャッシュを消去した後には自動的に呼ばれます。

— Function: int mpfr_mp_memory_cleanup (void)

mp_set_memory_functions関数を呼ぶ前にこの関数を呼ぶようにして下さい。詳細については See Memory Handlingをご覧下さい。 処理が成功した時はゼロを,エラーが発生した時には非ゼロを返します。 エラーが発生することは現状ない筈ですが,将来もきちんと動作させたいのであれば,返り値をチェックすることをお勧めします。

— Function: int mpfr_sum (mpfr_t rop, const mpfr_ptr tab[], unsigned long int n, mpfr_rnd_t rnd)

n個のtab要素の全ての和を求め,rnd方式で丸めてropに代入します。

[警告] 動作を高速化するために tabmpfr_tを要素とする配列へのポインタとなっており,mpfr_tの配列そのものではありません。 n = 0の時は+0となり,n = 1の時はmpfr_set関数と同じ動作を行います。 誤差なしで和が求められる特殊ケースの場合のみ, 通常の加算処理(mpfr_add関数)を無限桁で逐次行った時と同じ値を得ることができます。 特に,n >= 1で,正確な和がゼロになる場合は次のようになります。


Next: , Previous: Special Functions, Up: MPFR Interface

5.8 入出力関数

この節では,入出力ストリームを使用する入出力関数について解説します。 ここで述べる関数のstreamにNULLポインタを与えると,入力はstdinから,出力はstdoutに行うという意味になります。

FILE *を引数とする関数を使う時には,必ず<stdio.h>ヘッダファイルをmpfr.hより前の位置でインクルードして下さい。mpfr.hの中でこの型を用いた関数のプロトタイプを宣言しているからです。

— Function: size_t mpfr_out_str (FILE *stream, int base, size_t n, mpfr_t op, mpfr_rnd_t rnd)

出力ストリームstreamに,rnd方式で丸めて得たopbase進表現n桁の値を出力します。 基数は2以上62以下の自然数が指定できます。n桁の有効桁数は正確に出力されます。 nが0の時は,opを読み戻した時にも同じ出力結果が出せる程度に十分な桁数分出力します。 mpfr_get_str関数の説明も参照して下さい。

有効桁だけでなく,小数点も現時点のロケールに従って最初の桁の右側に出力されます。 その後に続く指数部は,‘eNNN’という形式の10進表現となります。 基数baseが10より大きい時には,指数部の区切り文字として‘e’ではなく,‘@’が使用されます。

関数の返り値は出力した文字数で,エラー発生時にはゼロが返ります。

— Function: size_t mpfr_inp_str (mpfr_t rop, FILE *stream, int base, mpfr_rnd_t rnd)

入力ストリームstreamからbase進表現の文字列を入力し,rnd方式で丸め, 浮動小数点型変数ropに代入します。

この関数は単語単位,つまりホワイトスペースの間の文字列を読み取り,mpfr_set_str関数 を使って処理ます。 有効な文字列形式についてはmpfr_strtofr関数の説明を参照して下さい。

返り値は読み取ったバイト数で,エラーが発生した場合はゼロが返ります。

— Function: int mpfr_fpif_export (FILE *stream, mpfr_t op)

opをファイルストリームstreamに,浮動小数点交換形式でエクスポートします。 特に,32ビットコンピュータとでエクスポートして,64ビットコンピュータでインポートしたり, リトルエンディアン環境でエクスポートしてビッグエンディアン環境でインポートしたりする場合に有用です。 opの精度桁数とNaNの符号もストアされます。 エクスポートが正常に行われた時のみゼロを返します。

[注記] この関数の実装は試験的なものなので,インターフェースが将来変わる可能性があります。

— Function: int mpfr_fpif_import (mpfr_t op, FILE *stream)

ファイルストリームstreamから浮動小数点交換形式(mpfr_fpif_export関数参照)で読み取りを行い, opにインポートします。 opの精度桁数はストリームから読み取ったもので,NaNであっても符号も常に読み取ります。 インポートされた精度桁数がゼロであったり,MPFR_PREC_MAXを越えたものである時は, インポートに失敗し,非ゼロを返してopには手を加えません。 他の理由でインポートに失敗した場合はopにはNaNがセットされます。また,opの精度桁数 についても,読み取りされたとしても不定になります。

インポートが正常に行われた時のみゼロを返します。

[注記] この関数の実装は試験的なものなので,インターフェースが将来変わる可能性があります。

— Function: void mpfr_dump (mpfr_t op)

形式は特に指定せずに,opを標準出力stdoutに改行付きで表示します。 主としてデバッグ用に使用する関数で,正常でないデータに対しても適用できます。 特に定めていない事項についてはABIを破壊しないよう,環境異存で決まります。

現状では次のような出力形式になっています。 符号ビットが立っていればNaNであってもマイナスを出力し, NaN, 無限大,ゼロに対してはそれぞれ‘@NaN@’, ‘@Inf@’,‘0’と出力します。 それ以外の値は,符号に続いて次のように出力されます。 ‘0.’に続いてpビットの2進仮数部表現(pは精度桁数),その後にゼロが続くようなら(通常のデータではあり得ないケース),大かっこを付けて出力します。大文字‘E’の後に10進表現の指数部が表示され, 不正なデータ形式や指数部範囲を超えている場合は,3つの感嘆詞(‘!!!’)を出力し,フラグに続いて, もう一度3つの感嘆詞(‘!!!’)を出力します。 フラグの意味は次の通りです。‘N’は仮数部の最大ビット(MSB)がゼロである,つまり正規化されていないことを意味し‘T’は,非ゼロなビットが続いていることを意味し,‘U’はUBF数(内部使用のみ)を意味し, ‘<’は指数部が現状の最小指数部値より小さいことを, ‘>’は指数部が現状の最大指数部値より大きいことを意味します。


Next: , Previous: Input and Output Functions, Up: MPFR Interface

5.9 書式指定出力関数

5.9.1 利用条件

mpfr_printf関数は書式指定された出力を,標準Cのprintf関数と同様に行うことができます。 ビルド対象のシステムでISO Cの可変長引数の関数と,可変長引数にアクセスするためのマクロがサポートされている場合のみ, この関数が使用できます。

この関数を使う際には,mpfr.hの前に,必ず<stdio.h>をインクルードしておく必要があります。 mpfr.hにおけるこの関数のプロトタイプ宣言で使用しているからです。

5.9.2 書式指定文字列

mpfr_printf関数で指定できる書式指定は,printf関数の書式指定を拡張したものになっています。書式指定の形式は次のようになっています。

     % [フラグ] [文字数] [.[精度桁数]] [データ型] [丸め方式] 変換形式

フラグ(flag)’, ‘文字数(width)’, ‘精度桁数(precision)’はprintf関数と同じ意味を持ちます。‘精度桁数(precision)’は変換形式で指定した基数(base)に基づいて表示される桁数となります。しかし,例えば‘Re’という書式指定を行うと,デフォルトの表示精度桁数は,‘e’という書式指定で設定した場合とは違ったものが設定されます。 mpfr_printf関数はGMPが提供するデータ型に対する書式指定と同じものが利用できます。但し,廃止予定の書式指定である‘q’ではなく,‘ll’と指定して下さい。

hshort
hhchar
jintmax_t または uintmax_t
llong または wchar_t
lllong long
Llong double
tptrdiff_t
zsize_t

上記は標準データ型にする書式指定で,これ加えて,GMPが定義する‘データ型(type)’と,MPFRのデータ型に対する‘R’指定と‘P’指定が利用できます。下記の表の2列目が,‘データ型(type)’に続く,‘変換形式(conv)’の書式指定となります。

Fmpf_t, 浮動小数点形式
Qmpq_t, 整数形式
Mmp_limb_t, 整数形式
Nmp_limb_t配列, 整数形式
Zmpz_t, 整数形式


Pmpfr_prec_t, 整数形式
Rmpfr_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’ ‘A16進浮動小数点表示, C99形式
b2進出力
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です。

5.9.3 書式指定入出力関数

下記の関数に対して,int型の最大値INT_MAXを超えるパラメータの設定がされている場合は,何も出力しません(出力先がstdoutでもbufでもstrであっても同じです)。 この場合,関数は−1を返し,範囲エラーフラグを立て,POSIX環境などEOVERFLOWマクロが定義されていればerrnoEOVERFLOWを代入します。注意してほしいのは, これ以外のエラー発生時(今のところ,メモリ解放関数で起こり得る)にも,内部ライブラリ呼び出しの結果, errnoの値は変化してしまう可能性があるということです。

— Function: int mpfr_fprintf (FILE *stream, const char *template, ...)
— Function: int mpfr_vfprintf (FILE *stream, const char *template, va_list ap)

出力先streamに対して,書式指定文字列templateに従った出力を行います。 返り値は出力した文字数で,エラー発生時は負数が返されます。

— Function: int mpfr_printf (const char *template, ...)
— Function: int mpfr_vprintf (const char *template, va_list ap)

標準出力stdoutに対して,書式指定文字列templateに従った出力を行います。 返り値は出力した文字数で,エラー発生時は負数が返されます。

— Function: int mpfr_sprintf (char *buf, const char *template, ...)
— Function: int mpfr_vsprintf (char *buf, const char *template, va_list ap)

NULL終端子を持つ文字列を,書式指定文字列templateに従って生成し, bufに格納します。bufと他の引数はメモリ内で重複してはいけません。 返り値はNULL終端子を除いてbufに書き込まれた文字数で,エラーが発生した場合は負数が返されます。

— Function: int mpfr_snprintf (char *buf, size_t n, const char *template, ...)
— Function: int mpfr_vsnprintf (char *buf, size_t n, const char *template, va_list ap)

NULL終端子を持つ文字列を,書式指定文字列templateに従って生成し, bufに格納します。nがゼロの時は何も書き込まず,bufはNULLポインタとなります。nに正数が指定される場合は,最初のn−1文字がbufに書き込まれ,n番目の文字がNULLになります。 nが十分大きい場合は,最後のNULL文字を除き,書き込まれた文字数が返り値となり,エラーが発生した場合は負数が返り値となります。

— Function: int mpfr_asprintf (char **str, const char *template, ...)
— Function: int mpfr_vasprintf (char **str, const char *template, va_list ap)

現在のメモリ割り当て関数(see Memory Handling)を使って確保したメモリブロックに,NULL終端子を持つ文字列を書き込みます。メモリブロックへのポインタはstrに与えます。メモリブロックを解放するときには必ずmpfr_free_strを使って下さい。 返り値はNULL終端子を除いて書き込まれた文字数で,エラーが発生した場合は負数が返され,strの値は不定となります。


Next: , Previous: Formatted Output Functions, Up: MPFR Interface

5.10 整数関数,剰余関数

— Function: int mpfr_rint (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_ceil (mpfr_t rop, mpfr_t op)
— Function: int mpfr_floor (mpfr_t rop, mpfr_t op)
— Function: int mpfr_round (mpfr_t rop, mpfr_t op)
— Function: int mpfr_roundeven (mpfr_t rop, mpfr_t op)
— Function: int mpfr_trunc (mpfr_t rop, mpfr_t op)

opを丸めて整数にしてropに代入します。 mpfr_rint関数は,rnd方式を用いて最も近い整数に丸めます。他の5つの関数も,丸め方式を固定して整数に丸めます。

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となります。

— Function: int mpfr_rint_ceil (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_rint_floor (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_rint_round (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_rint_roundeven (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)
— Function: int mpfr_rint_trunc (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opを丸めて整数化してropに代入します。

素直に整数化できない時には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に近いのですが。

— Function: int mpfr_frac (mpfr_t rop, mpfr_t op, mpfr_rnd_t rnd)

opの小数部をrnd方向に丸めて取り出し,符号も等しくなるようにropに代入します。 mpfr_rint関数と同様に, rndは正確な小数部を丸める時にのみ影響し,小数部の取り出しには影響を与えません。 opが整数,もしくは無限大の時はropにはopと同符号のゼロを代入します。

— Function: int mpfr_modf (mpfr_t iop, mpfr_t fop, mpfr_t op, mpfr_rnd_t rnd)

opの整数部をiopに,小数部をfopに同時に代入します。 それぞれrnd方向に丸めてiopfopの精度桁数に納めます。 これはmpfr_trunc(iop, op, rnd)mpfr_frac(fop, op, rnd))と同じ処理になります。変数iopfopは異なる変数でなければなりません。どちらも正確な値を返すことができた時のみゼロを返します。 mpfr_sin_cos関数の返り値についての記述も参照して下さい。

— Function: int mpfr_fmod (mpfr_t r, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)
— Function: int mpfr_fmodquo (mpfr_t r, long* q, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)
— Function: int mpfr_remainder (mpfr_t r, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)
— Function: int mpfr_remquo (mpfr_t r, long* q, mpfr_t x, mpfr_t y, mpfr_rnd_t rnd)

x - nyの値を計算し,rnd方式で丸めてrに代入します。 ここでnは,xyで割った時の整数の商で,次のように定義されます。 nmpfr_fmod関数とmpfr_fmodquo関数を用いてゼロ方向に丸められ, mpfr_remainder関数と mpfr_remquo関数に対しては偶数丸めで最近接の整数になります。

特殊値については,ISO C99規格のF.9.7.1節に述べられているように扱います。 xが無限大,もしくはyがゼロの時は,rはNaNになります。 yが無限大でxが有限値の時は,rxrの精度桁数に丸められた値になります。 rがゼロの時は,xと同符号になります。 返り値はrに応じた三種値になります。

加えて,mpfr_fmodquo関数とmpfr_remquo関数は *qにおける商nの低位のビットを,xyで割った時の符号と共に格納します。 正確に言うと,long型のビット数から1少ないビット数分ということになります。 但し,全てのビットがゼロの時は除きます。この時はゼロを返します。 xは,正しい商が実用的なものではないyに比して絶対値が大きくなる可能性があります。 mpfr_remainder関数とmpfr_remquo関数は引数のリダクション用に使用されています。

— Function: int mpfr_integer_p (mpfr_t op)

opが整数の時のみ,ゼロ以外の数を返します。


Next: , Previous: Integer and Remainder Related Functions, Up: MPFR Interface

5.11 丸め処理関数

— Function: void mpfr_set_default_rounding_mode (mpfr_rnd_t rnd)

デフォルトの丸めモードをrndに設定します。 初期設定では最近偶数丸めがデフォルトです。

— Function: mpfr_rnd_t mpfr_get_default_rounding_mode (void)

現在のデフォルトの丸めモードが返されます。

— Function: int mpfr_prec_round (mpfr_t x, mpfr_prec_t prec, mpfr_rnd_t rnd)

xrnd方式で丸め,精度桁数precに納めます。精度桁数はMPFR_PREC_MIN以上,MPFR_PREC_MAX以下 でなければなりません。そうでない時の動作は定義されていません。 precxの精度桁数以上であれば,新たに仮数部を格納するために必要なメモリ領域を確保し,下の桁にはゼロが詰め込まれます。 precxの精度桁数未満であれば,指定された丸めモードで仮数部は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ビットに丸められる */

[警告] この関数で使用するxMPFR_DECL_INITマクロや,mpfr_custom_init_set関数 (see Custom Interface)で絶対に初期化しないで下さい。

— Function: int mpfr_can_round (mpfr_t b, mpfr_exp_t err, mpfr_rnd_t rnd1, mpfr_rnd_t rnd2, mpfr_prec_t prec)

bを未知数xrnd1方向に丸め,2の E(b)-err乗の誤差を持つ近似値と仮定します。ここでE(b)はbの指数部を意味します。この時,指数部の範囲制限はないものとして, xを正しくrnd2方向に丸めてprec桁にできるのであれば,この関数は非ゼロを返します。 それ以外の場合は,NaNや無限大の場合も含めて0を返します。 言い換えると,bの誤差が2の k乗 ulp以下で抑えられ,bprec桁の精度を持っているならば, err=preckという評価式を得られるということです。 この関数は,引数を変更しません

rnd1MPFR_RNDNもしくはMPFR_RNDFである時には, 誤差は正もしくは負になると想定されますので,誤差範囲はrnd1が行う丸めの2倍,つまり errと同じ値になります。

rnd2MPFR_RNDFの時, rnd3にはrnd1とは反対方向の丸め方式を設定するものとします。 rnd1MPFR_RNDNもしくはMPFR_RNDFの時は,rnd3にはMPFR_RNDNを設定します。 さすれば,mpfr_can_round (b, err, rnd1, MPFR_RNDF, prec)の返り値は, mpfr_set (y, b, rnd3)prec桁のyで呼び出した後に, yxの忠実丸め結果と等しくなると保証できる時のみ,非ゼロを返します。

[注記] この関数については,返り値が三種値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);
            }

実際,rnd2MPFR_RNDNであれば,方向付き丸めでprec+1ビットに丸められるかどうかを 確認できます。 これができるなら,最近接丸めで確実にprec ビットになりますし,加えて, 非ゼロ三種値のどれになるかも正しく決められます。 ただし,bprec ビットで表現できる数に近接しているときはその限りではありません。

この関数についての詳細な事例はexamplesサブディレクトリにあるcan_round.cを参照して下さい。

— Function: mpfr_prec_t mpfr_min_prec (mpfr_t x)

xの仮数部を格納するために必要となる最小のビット数を返します。 xがゼロや非数など特別な数の場合は,0を返します。

— Function: const char * mpfr_print_rnd_mode (mpfr_rnd_t rnd)

丸め方式rndに対して,その丸めモードを表わす文字列("MPFR_RNDD", "MPFR_RNDU", "MPFR_RNDN", "MPFR_RNDZ","MPFR_RNDA")を返します。rndが丸めモードとして不適切な値の時は,NULLポインタを返します。

— Macro: int mpfr_round_nearest_away (int (foo)(mpfr_t, type1_t, ..., mpfr_rnd_t), mpfr_t rop, type1_t op, ...)

1ないし複数の引数op(データ型はmpfr_t, long, doubleなど)を取る関数fooを与え, ropfoo(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: , Previous: Rounding-Related Functions, Up: MPFR Interface

5.12 その他の関数

— Function: void mpfr_nexttoward (mpfr_t x, mpfr_t y)

xyのどちらかがNaNであれば,xにはNaNが代入され, 他の場合と同様,NaN フラグも立ちます。 xyが等しい時はxは変更されません。 それ以外の場合は,xyと異なる場合は,xは, xの精度桁数と現状の指数部の範囲で,y方向に隣の浮動小数点数が代入されます。 無限大の場合は,最小あるいは最大の浮動小数点数として機能します。 結果がゼロの時は,符号は同じものが保持されます。 アンダーフロー,オーバーフロー,不正確例外が発生することはありません。

— Function: void mpfr_nextabove (mpfr_t x)
— Function: void mpfr_nextbelow (mpfr_t x)

yが正の無限大(負の無限大)の時のmpfr_nexttoward関数と同じ処理を行います。

— Function: int mpfr_min (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)
— Function: int mpfr_max (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

ropop1op2の最小値(最大値)を代入します。op1op2が共にNaNの時は,ropにもNaNが代入されます。op1op2のどちらかがNaNの時は,ropには有限数値の方が代入されます。 op1op2が互いに符号の異なるゼロの時は,ropには −0 (+0)が代入されます。

— Function: int mpfr_urandomb (mpfr_t rop, gmp_randstate_t state)

0 <= rop < 1区間の一様乱数を浮動小数点数として与えます。 正確に言うと,この乱数は正規化されていない仮数部と指数部がゼロの浮動小数点数として表現されます。 当然,最終的には正規化されて指数部がeとなりますから,仮数部の最後のeビットは常にゼロとなります。

指数部が現状の指数部範囲に収まっていれば0を返し,指数部範囲を超えていればropにはNaN を代入し,非ゼロを返します。とはいえ指数部範囲を超えるということは普通は起こりません。 2番目の引数は,gmp_randstate_t構造体で,GMPのgmp_randinit関数を使って 生成しておいて下さい(GMPマニュアル参照)。

[注記] MPFRでは,ropに代入される値や,以降の乱数を制御するstateの新しい値 は,マシンのワードサイズには依存せずに決まります。

— Function: int mpfr_urandom (mpfr_t rop, gmp_randstate_t state, mpfr_rnd_t rnd)

一様分布に従う浮動小数点数を生成します。 浮動小数点数ropは,[0, 1]区間の連続一様分布に従う実数乱数がrnd方向に丸められた 値と見ることができます。

2番目の引数であるgmp_randstate_t構造体はGMPのgmp_randinit関数で生成したものを 指定して下さい(GMPマニュアル参照)。

[注記] mpfr_urandombの注記はこの関数でも有効です。さらに言うと, 丸められる前の正しい乱数値と次の乱数状態は,現状の指数部範囲と丸めモードはに依存しませんが, 代入される変数の精度桁数には依存します。つまり,乱数生成器の状態が同じものから出発したとしても, 代入される変数の精度桁数が変更されると,その値や乱数生成器の状態は完全に違ったものに変化します。

— Function: int mpfr_nrandom (mpfr_t rop1, gmp_randstate_t state, mpfr_rnd_t rnd)
— Function: int mpfr_grandom (mpfr_t rop1, mpfr_t rop2, gmp_randstate_t state, mpfr_rnd_t rnd)

平均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関数は廃止予定で,将来消去される予定です。

— Function: int mpfr_erandom (mpfr_t rop1, gmp_randstate_t state, mpfr_rnd_t rnd)

平均が1の指数分布に従う乱数を浮動小数点数として与えます。 その他の性質はmpfr_nrandom関数と同じです。

— Function: mpfr_exp_t mpfr_get_exp (mpfr_t x)

xは通常の非ゼロな浮動小数点数で,仮数部は[1/2,1)に存在しているという前提で,xの指数部を返します。 この関数では xが現状の指数部範囲を超えていても正しく処理を行います。 xがNaN, 無限大,ゼロの時の処理は定めていません。

— Function: int mpfr_set_exp (mpfr_t x, mpfr_exp_t e)

xが通常の非ゼロの浮動小数点数である時,xの指数部にeを代入します。 eが現状の指数部範囲に収まっていればゼロを返し,それ以外の時は, 非ゼロを返し,xは変更しません。

— Function: int mpfr_signbit (mpfr_t op)

opの符号部がセット,つまり負数や,−0, 符号部の設定されたNaNの時のみ非ゼロを返します。

— Function: int mpfr_setsign (mpfr_t rop, mpfr_t op, int s, mpfr_rnd_t rnd)

opを丸め方式rndで丸め,ropに代入し,しかる後にsの値が非ゼロ(ゼロ)の時は,符号も代入(クリア)します。 これはopがNaNの場合も同様に処理されます。

— Function: int mpfr_copysign (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

op1を丸め方式rndで丸めてropに代入し,その符号ビットをop2に代入します。 op1op2がNaNであっても同様に処理されます。この関数は mpfr_setsign (rop, op1, mpfr_signbit (op2), rnd)と同じ働きを行います。

— Function: const char * mpfr_get_version (void)

NULL終端子付きの文字列としてMPFRのバージョンを返します。

— Macro: MPFR_VERSION
— Macro: MPFR_VERSION_MAJOR
— Macro: MPFR_VERSION_MINOR
— Macro: MPFR_VERSION_PATCHLEVEL
— Macro: MPFR_VERSION_STRING

MPFR_VERSIONは定数として与えられるMPFRのバージョン番号です。 MPFR_VERSION_MAJOR, MPFR_VERSION_MINORMPFR_VERSION_PATCHLEVELはそれぞれ,MPFRのメジャー番号,マイナー番号,パッチレベルを表わす定数です。 MPFR_VERSION_STRINGは,文字列定数として与えられるバージョン定数で,開発バージョンやプレリリース用のバージョンに使用されるサフィックスも含まれています。この文字列定数はmpfr_get_versionと比較でき,ヘッダファイルやライブラリをチェックする際に役立ちます。

          if (strcmp (mpfr_get_version (), MPFR_VERSION_STRING))
          
            fprintf (stderr, "警告: ヘッダファイルとライブラリのバージョンが一致していません。\n");

[注記] 上記のように比較して文字列が一致しなくてもエラーとは言えません。 古いMPFRバージョン用に作ったプログラムは,ライブラリのバージョン管理システムが許可していれば, 新しいバージョンのMPFRと動的リンクすることもできます。

— Macro: long MPFR_VERSION_NUM (major, minor, patchlevel)

major, minorpatchlevelから,MPFR_VERSIONと同じ形式の整数値を 生成します。 下記は,コンパイル時にMPFRのバージョンをチェックするプログラム例です。

          #if (!defined(MPFR_VERSION) || (MPFR_VERSION<MPFR_VERSION_NUM(3,0,0)))
          
          # error "MPFRのバージョンが正しくありません。"
          #endif
— Function: const char * mpfr_get_patches (void)

MPFRライブラリに適用されたパッチ(内容はPATCHESファイルに書いてあります)のidを含む,NULL終端子文字列を返します。 文字列はスペースで区切られています。

[注記] 古いMPFRとコンパイルしたプログラムを新しいMPFRと動的リンクするのであれば, コンパイル時の古いMPFRの識別子は無効になります。 まぁ大して重要な情報ではありませんので。

— Function: int mpfr_buildopt_tls_p (void)

MPFRがスレッドセーフになるよう,スレッドローカルなストレージを有効にしてコンパイルされた時には (‘--enable-thread-safe’オプションつきで設定します。INSTALLファイルを参照のこと),非ゼロを返します。 スレッドセーフでない時にはゼロを返します。

— Function: int mpfr_buildopt_float128_p (void)

MPFRが‘__float128’をサポートしている時には非ゼロを返します。 つまり,MPFRが‘--enable-float128’オプション付きで設定するとそうなります。 サポートしていない時はゼロを返します。

— Function: int mpfr_buildopt_decimal_p (void)

MPFRを‘--enable-decimal-float’オプション付きで設定するとMPFRは10進浮動小数点数をサポートしますが, この時にはこの関数は非ゼロを返します。 サポートしていない時はゼロを返します。

— Function: int mpfr_buildopt_gmpinternals_p (void)

MPFRが‘--with-gmp-build’オプション,もしくは ‘--enable-gmp-internals’オプション付きでビルドされていると,MPFRはGMPの内部関数を 利用します。この時この関数は非ゼロを返します。そうでない時にはゼロを返します。

— Function: int mpfr_buildopt_sharedcache_p (void)

MPFRが全てのスレッドでmpfr_const_pimpfr_const_log2などのMPFR定数を保持するキャッシュを共有するようにコンパイルされていると(‘--enable-shared-cache’オプション付きでビルドした場合),非ゼロを返します。 キャッシュ共有ができない場合はゼロを返します。 この関数が非ゼロを返す時には,MPFRを使用するアプリケーションは,‘-pthread’オプションを付けてコンパイルする必要があります。

— Function: const char * mpfr_buildopt_tune_case (void)

コンパイル時に使用した閾値ファイルを文字列で返します。 このファイルは通常,プロセッサの種類ごとに決まっています。


Next: , Previous: Miscellaneous Functions, Up: MPFR Interface

5.13 例外処理関数

— Function: mpfr_exp_t mpfr_get_emin (void)
— Function: mpfr_exp_t mpfr_get_emax (void)

関数実行時点における,MPFR浮動小数点型の指数部の最小値と最大値をそれぞれ返します。 浮動小数点型の正の最小値は1/2に2の指数部最小値乗を掛けたもの, 正の最大値は(1 - epsilon) に2の指数部最大値乗を掛けたものです。 ここで,epsilonは浮動小数点型の精度桁数によって決まる定数です。

— Function: int mpfr_set_emin (mpfr_exp_t exp)
— Function: int mpfr_set_emax (mpfr_exp_t exp)

浮動小数点型の指数部の最小値と最大値をそれぞれ設定します。 expを,実行環境に依存して決まる指数部の範囲内で最小値,あるいは最大値として設定できない場合は非ゼロ数を返します。この場合は,現状の指数部最小値ないし指数部最大値は変化しません。指数部の最小値・最大値を設定できれば,ゼロを返します。

これらの関数の実行後は,ユーザの責任で入力される浮動小数点数が,mpfr_check_range関数を使用するなどして,この新しい指数部の範囲内に収まっていることをチェックする義務が生じます。 この範囲からはみ出している値が入力された時のデフォルトの動作は,ISO C規格でも決まっていません。mpfr_check_range関数にあるように,その際の挙動については明文化されています。

[注記] 定数値のキャッシュは,これらの関数で指数部の範囲が変更された後もそのままです。 これは,API経由でキャッシュ値を直接ユーザが使うことができない,ということではありません。 MPFRは,必要に応じて指数部の範囲を超えること内部的には許容します。

emin > emaxかつ,浮動小数点値を出力しなければならない場合は, その挙動は不定です。mpfr_set_emin関数も mpfr_set_emax関数もこの条件はスルーしますし,いつでも起こり得る事象ではあります。

— Function: mpfr_exp_t mpfr_get_emin_min (void)
— Function: mpfr_exp_t mpfr_get_emin_max (void)
— Function: mpfr_exp_t mpfr_get_emax_min (void)
— Function: mpfr_exp_t mpfr_get_emax_max (void)

mpfr_set_emin関数やmpfr_set_emax関数で設定できる指数部の最小値と最大値をそれぞれ返します。 これらの値は事項環境に依存しますので, mpfr_set_emax(mpfr_get_emax_max())mpfr_set_emin(mpfr_get_emin_min())といったことを行うと,ポータビリティを損ねます。

— Function: int mpfr_check_range (mpfr_t x, int t, mpfr_rnd_t rnd)

この関数は,xyrnd方式で,指数部の範囲も拡張して正しく丸めた値になっており, tには三種値(ternary value)が入っていることを仮定しています。 例えば,t = mpfr_log (x, u, rnd)で,yuの自然対数の正しい値が入っているものとします。 さすれば,tは,xyより小さい時には負数, xyより大きければ正数,xyが等しければゼロになります。 この関数は,xが現状受け入れ可能な値の範囲に入っていれば,値を入れなおします xの指数部が現状の許容範囲から外れていれば,オーバーフローもしくはアンダーフローが発生します。 tの値は2重に丸めが発生することを防止するために使用されます。 新しいxの値が真値であるyと等しい時にはゼロを, yより大きくなる場合は正数を, yより小さくなる場合は負数を返します。 他の関数とは違い, 新しいxの値は(未知の)真値であるyと比較し, 入力時のxとは比較しません。つまり,三種値は伝達されます。

[注記] xが無限大で,tが非ゼロである時(つまり,丸めた結果,不正確な無限大になった時) オーバーフラグが立てられます。 これが役に立つのは,mpfr_check_range関数が,MPFRの関数内で呼ばれ,内部処理でフラグがセット される場合です。

— Function: int mpfr_subnormalize (mpfr_t x, int t, mpfr_rnd_t rnd)

この関数は,非正規数演算(subnormal)をエミュレートしつつ,xを丸めます。xが非正規化エリアの外にある場合は, 三種値ternary value tだけを伝えます。 xが非正規エリアに入っている時には, 丸めモードrndと,引数の三種値tに従って,二重に丸めを行わないようにしつつ,xEXP(x)-emin+1精度桁数に丸めます。正確に言うと,非正規化エリアの中では,eeminの値になり,xは丸められて固定小数点演算用として2の e−1乗を掛けられて整数になります。結果として1.5 に2のe−1乗を掛けたもの,tがゼロの時は 2のe乗を最近接値に丸めます。

PREC(x)はこの関数では変更されません。 rndは丸めモード,txが計算される際に使われる三種値でなければなりません。 これはmpfr_check_range関数と同じです。 非正規化エリアとなる指数部の範囲は,eminからemin+PREC(x)-1までとなります。 emaxの設定値が小さすぎる場合など,現状のMPFRの許容指数部の範囲内では結果が表現できない時のこの関数 の挙動は定義されていません。 他の関数とは異なり,演算結果は,入力時のxではなく,真値と比較されます。 つまり,三種値は引数の値が引き継がれます。

通常は,返り値の三種値がゼロの場合,不正確フラグが立ちます。 更に,入力値xが最初から非正規化エリアの値だったりして,2回目の丸め処理が起きた場合は アンダーフローフラグがセットされます。

[警告] mpfr_subnormalize関数を呼び出す前にeminmpfr_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);
     }
— Function: void mpfr_clear_underflow (void)
— Function: void mpfr_clear_overflow (void)
— Function: void mpfr_clear_divby0 (void)
— Function: void mpfr_clear_nanflag (void)
— Function: void mpfr_clear_inexflag (void)
— Function: void mpfr_clear_erangeflag (void)

それぞれアンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラーフラグをクリアします。

— Function: void mpfr_clear_flags (void)

全てのグローバルフラグ(アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラー)をクリアします。

[注記] フラグのグループをまとめてクリアするためのmpfr_flags_clear関数も使用可能です。

— Function: void mpfr_set_underflow (void)
— Function: void mpfr_set_overflow (void)
— Function: void mpfr_set_divby0 (void)
— Function: void mpfr_set_nanflag (void)
— Function: void mpfr_set_inexflag (void)
— Function: void mpfr_set_erangeflag (void)

アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラーフラグを立てます。

— Function: int mpfr_underflow_p (void)
— Function: int mpfr_overflow_p (void)
— Function: int mpfr_divby0_p (void)
— Function: int mpfr_nanflag_p (void)
— Function: int mpfr_inexflag_p (void)
— Function: int mpfr_erangeflag_p (void)

それぞれ,対応するフラグ (アンダーフロー,オーバーフロー,ゼロ除算,不正な計算,不正確演算,範囲エラー )を返します。フラグが立っている時のみ,非ゼロ数を返します。

以下のmpfr_flags_関数群は,maskという引数を取りますが,これは 例外フラグを自在に操るためのものです。 一つのフラグは,対応するmaskの当該ビットがセットされている時のみ,例外フラグの集合の一部となります。 MPFR_FLAGS_マクロは,このmaskを設定するために使用されます。See Exceptionsもご参照下さい。

— Function: void mpfr_flags_clear (mpfr_flags_t mask)

maskで指定されたフラグのグループをクリアします。

— Function: void mpfr_flags_set (mpfr_flags_t mask)

maskで指定されたフラグのグループを立てます。

— Function: mpfr_flags_t mpfr_flags_test (mpfr_flags_t 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)   { /* オーバーフローを制御 */ }
            }
— Function: mpfr_flags_t mpfr_flags_save (void)

全てのフラグを返します。これは mpfr_flags_test(MPFR_FLAGS_ALL)と同じ意味になります。

— Function: void mpfr_flags_restore (mpfr_flags_t flags, mpfr_flags_t mask)

maskで特定されたフラグの状態をflagsに格納します。


Next: , Previous: Exception Related Functions, Up: MPFR Interface

5.14 MPFとの互換性

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ではいくつか異なる点があります。特に下記のようなものが挙げられます。

— Function: void mpfr_set_prec_raw (mpfr_t x, mpfr_prec_t prec)

xの精度桁数を正確にprecビットに設定し直します。 mpfr_set_prec関数との違いは,precは仮数部が現状の変数xのメモリ領域に収まる ぐらいのものになっていることを仮定していることです。そうでなければ,この関数の振る舞いは不定となります。

— Function: int mpfr_eq (mpfr_t op1, mpfr_t op2, unsigned long int op3)

op1op2とが,ともに通常の浮動小数点数で,等しい指数部を持ち,仮数部の冒頭op3ビットが等しいか,両方ともゼロか,同じ符号を持つ無限大であるか,これらのいずれかであれば,非ゼロ数を返します。 この関数はMPFの対応する関数との互換性のために定義されたもので,それ以外の目的には使用しないことをお勧めします。 この関数は,2数が近接しているかどうかを確認したい時には使用しないで下さい。例えば, 1.011111 と1.100000は,op3が1を超える時には等しくないものとして扱われます。

— Function: void mpfr_reldiff (mpfr_t rop, mpfr_t op1, mpfr_t op2, mpfr_rnd_t rnd)

op1op2の相対差を計算し,その結果をropに代入します。 この関数は,相対差に関しては正しい丸めを保証しません。 単純に|op1-op2|/op1ropの精度桁数とrnd方式で計算して丸めます。

— Function: int mpfr_mul_2exp (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)
— Function: int mpfr_div_2exp (mpfr_t rop, mpfr_t op1, unsigned long int op2, mpfr_rnd_t rnd)

これらの関数はmpfr_mul_2ui関数やmpfr_div_2ui関数と同一のものです。 MPFの互換性のために残された関数なので,その必要がなければmpfr_mul_2ui関数やmpfr_div_2ui関数の利用をお勧めします。


Next: , Previous: Compatibility with MPF, Up: MPFR Interface

5.15 カスタムインターフェース

幾つかのアプリケーションでは,スタックを使ってメモリやオブジェクトの操作を行います。 しかし,MPFRのメモリデザインは,そういう目的には向ていません。 それ故,その手のアプリケーションでMPFRが使用できるようにするのであれば,補助的なメモリインターフェース がなくてはなりません。それがカスタムインターフェースです。

これらの機能をMPFRで使用できるようにするには,下記の二つの方法があります。

浮動小数点数を削除するには,使用したメモリをガベージコレクションに為すがままにさせておくしかありません。 全てのメモリ管理機能(割り当て,破壊,解除)はアプリケーションにお任せするのです。

このインターフェースのための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関数を呼ばなくてはなりません。

— Function: size_t mpfr_custom_get_size (mpfr_prec_t prec)

精度桁数precビットの仮数部を格納するのに必要なバイト数を返します。

— Function: void mpfr_custom_init (void *significand, mpfr_prec_t prec)

精度桁数precビットの仮数部を初期化します。ここで significandmpfr_custom_get_size (prec)バイトのメモリ領域が最低でも必要で,mp_limb_t型 (GMPのデータ型,see Internals参照)の配列になっていなければなりません。

— Function: void mpfr_custom_init_set (mpfr_t x, int kind, mpfr_exp_t exp, mpfr_prec_t prec, void *significand)

mpfr_t型のダミー初期化を実行し,次のように値をセットします。

全ての場合に共通するのは,significandxを使う以降の計算に直接利用されるということです。 この関数はメモリ領域の確保は行いません。この関数で初期化される浮動小数点数は mpfr_set_prec関数やmpfr_prec_round関数を使ったリサイズや,mpfr_clear関数を使ったメモリ解放は出来ません。 significandは,同じ精度桁precを引数に渡したmpfr_custom_init関数を使って初期化しなくてはいけません。

— Function: int mpfr_custom_get_kind (mpfr_t x)

mpfr_custom_init_set関数を使って生成されたmpfr_t型データの種類を返します。 mpfr_custom_init_set関数を使用せずに初期化されたmpfr_t型データが渡された時の動作は定義されていません。

— Function: void * mpfr_custom_get_significand (mpfr_t x)

mpfr_custom_init_set関数を使って初期化されたmpfr_t型データの仮数部へのポインタを返します。 mpfr_custom_init_set関数を使用せずに初期化されたmpfr_t型データが渡された時の動作は定義されていません。

— Function: mpfr_exp_t mpfr_custom_get_exp (mpfr_t x)

xが非ゼロの通常の浮動小数点数で,仮数部が[1/2,1)にあると想定される時,xの指数部を返します。 xがNaN,無限大,ゼロのように,mpfr_get_exp関数の挙動が定義されていない値である時, 返り値は不定となりますが,mpfr_exp_t型の有効な数になります。 mpfr_custom_init_set関数を使用せずに初期化されたmpfr_t型データが渡された時の動作は定義されていません。

— Function: void mpfr_custom_move (mpfr_t x, void *new_position)

MPFRに,xの仮数部がガベージコレクションによって移動され,新しい位置に収まっていると知らせます。 とはいえ,アプリケーション自体が仮数部とmpfr_t型データを移動するようにしないといけません。 mpfr_custom_init_set関数を使用せずに初期化されたmpfr_t型データが渡された時の動作は定義されていません。


Previous: Custom Interface, Up: MPFR Interface

5.16 MPFRの内部構造

リム(limb)は,1ワードを単位とする多倍長精度浮動小数点数の構成要素を意味します。 1リムは通常,32ビットか64ビットです。リムを表わすCデータ型はmp_limb_tです。

mpfr_tデータ型は,内部的には構造体の配列の1つ分として定義されており,mpfr_ptr型は,この構造体へのポインタを表現しているデータ型です。 mpfr_tデータ型は,次の4つのフィールドから構成されています。


Next: , Previous: MPFR Interface, Up: Top

6 APIの互換性

本節では,MPFRのバージョンアップに伴って変化したAPIについて解説し,古いMPFRでもコンパイルできるプログラムの書き方について述べます。 但し,MPFR 2.2.0 (2005年9月20日リリース)以降のものについてのみフォローします。

APIの変更は,バージョン番号の最上位,もしくはその下の桁が変わった時に行われ,パッチレベル の変更(MPFRバージョン番号の第3桁目)では行われません。MPFRの内部構造を利用するようなプログラムでなければ, バグフィックスや意図しない動作による影響以上の変更は行われません。

一般的なルールとして,MPFRを利用するプログラムは,メジャーバージョンアップでも しない限り,多少のアップデートしたMPFRでも動くように書くべきで,廃止予定 と予告されている機能はそのうち使えなくなります。 そのような場合,コンパイルやリンク時にエラーを起こすことになります。 アップデートに伴う変更が原因で結果がおかしくなるようなら,これ以降に 記述してある,使用バージョンに関するFAQやMPFRのWebページにある変更点(最小限度にとどめていますので,ほとんどのソフトウェアでは 影響はないでしょう)を確認してみて下さい。 バグ混入や,既に修正されているものもあります。 特に記述がない場合は,バグ報告を送って下さい(see Reporting Bugs)。

しなしながら,現在のMPFRを利用したプログラムは,このマニュアルに書いてある通り, 以前のバージョンのMPFRで動作させる必要はないはずです。 この節では,ポータブルなプログラムを書くための情報を提供します。

[注記] ここに記した情報は網羅的なものではありませんので,APIの変更情報については MPFRのそれぞれのバージョンごとに提供されるNEWSファイルを参照して下さい。諸々の 更新情報も併せて掲載されています。


Next: , Previous: API Compatibility, Up: API Compatibility

6.1 データ型とマクロの変更

指数部の公式なデータ型をmp_exp_tからmpfr_exp_tに変更したのはMPFR 3.0からです。 mp_exp_tデータ型はGMPではこれからも違った意味で使用されると思われます。 この二つのデータ型は現状同じものです(mpfr_exp_ttypedefmp_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_tmp_rnd_tから, mpfr_prec_tmpfr_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_tmp_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_clearmpfr_flags_restore, mpfr_flags_setmpfr_flags_testも同様です。


Next: , Previous: Type and Macro Changes, Up: API Compatibility

6.2 追加された関数

ここでは,アルファベット順に,MPFR 2.2以降に追加されてきた関数と関数ライクなマクロを,追加時のMPFRバージョンと共に列挙します。


Next: , Previous: Added Functions, Up: API Compatibility

6.3 変更された関数

ここに記した関数はMPFR 2.2以降に変更がなされています。これらの変更により, 使用するMPFRのバージョンとの組み合わせ次第でプログラムの挙動が変わるかもしれません。


Next: , Previous: Changed Functions, Up: API Compatibility

6.4 削除された関数

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

6.5 その他の変更点

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のチェックするのは止め,次の方法を試して下さい。

ゼロ除算例外はMPFR 3.1で新たに追加されたものですが,この例外を使うのは このバージョン以降に追加された新しい関数だけなので,この導入によって互換性に 問題が生じることはありません。

MPFR 3.1以降では,mpfr.hヘッダファイルを複数回インクルードできます。また 追加された関数もあります (see Headers and Libraries)。

MPFRのメモリ割り当て方法については,MPFR 4.0で整理されたものをそのまま順守すべきです。


Next: , Previous: API Compatibility, Up: Top

7 MPFRとIEEE 754浮動小数点標準規格

この節では,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も同一のものとして扱います。 このような演算結果を現在のIEEE 754規格の観点から見ると,MPFRの現時点におけるポリシーは IEEE 754改定の浮動小数点演算ワーキンググループでは議論の対象外としたいもののようです。

MPFRでは,変数ごとに自身の精度桁数を持ち,この点IEEE754規格とは全く異なっているという事実も思い出して下さい。例えば,同一符号を持つ2数の減算を行うと,オーバーフローが発生する可能性があります。同様に,mpfr_set関数,mpfr_neg関数,mpfr_abs関数でも,精度桁数が少ないとオーバーフローが起きるかもしれません。


Next: , Previous: MPFR and the IEEE 754 Standard, Up: Top

MPFR貢献者一覧

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´enaire,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: , Previous: Contributors, Up: Top

参考文献


Next: , Previous: References, Up: Top

Appendix A GNU Free Documentation License

Version 1.2, November 2002
     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.
  1. PREAMBLE

    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.

  2. APPLICABILITY AND DEFINITIONS

    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.

  3. VERBATIM COPYING

    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.

  4. COPYING IN QUANTITY

    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.

  5. MODIFICATIONS

    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:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    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.

  6. COMBINING DOCUMENTS

    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.”

  7. COLLECTIONS OF DOCUMENTS

    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.

  8. AGGREGATION WITH INDEPENDENT WORKS

    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.

  9. TRANSLATION

    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.

  10. TERMINATION

    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.

  11. FUTURE REVISIONS OF THIS LICENSE

    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.

A.1 ADDENDUM: How to Use This License For Your Documents

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: , Previous: GNU Free Documentation License, Up: Top

Concept Index


Previous: Concept Index, Up: Top

Function and Type Index