Next: Rational Internals, Previous: Internals, Up: Internals [Index]
mpz_t
型の変数は,符号付き整数を表現するためのもので,動的にメモリ割り当て,再割り当てができます。この変数は次のような構成になっています。
_mp_size
リムの数を表わします。負の整数の場合はこの値もマイナスになります。ゼロの場合は,_mp_size
もゼロになり,_mp_d
の値は参照されません。
_mp_d
割り当て済みのリムの配列へのポインタです。リム配列は,mpn
型同様に「リトルエンディアン」形式で格納されていますので,_mp_d[0]
に最小桁にあたるリムが入り,_mp_d[ABS(_mp_size)-1]
に最大桁が格納されます。_mp_size
が非ゼロであれば,格納してある整数の最大桁も非ゼロになります。
現時点では常に1リムは確保するように実装されていますので,例えばmpz_set_ui
関数が再割り当てをするようなことはありませんし, mpz_get_ui
関数は必ず_mp_d[0]
を参照(fetch)します(_mp_size
が非ゼロであれば必要になるので)。
_mp_alloc
_mp_alloc
は現時点で_mp_d
に割り当てられているリムの数を意味します。従って,当然_mp_alloc >= ABS(_mp_size)
となります。mpz
ルーチンが_mp_size
を増やそうとしている(もしくは増やす可能性のある)時には_mp_alloc
をチェックして,十分な領域があるかどうかを確認し,足りなければ再割り当てを行います。この時にはMPZ_REALLOC
関数が使用されます。
様々な論理ビット演算を行う関数,例えばmpz_and
などは,負の値は2の補数であるとして扱います。しかし,符号も絶対値も常に参照され,必要な値の変更は計算中に実行されます。不都合なこともままありますが,符号と絶対値は他の関数にとっては最高に便利なツールなのです。
MPZ_TMP_INIT
関数と共にいくつかの内部一時変数が確保されます。 これはメモリ割り当て関数ではなく TMP_ALLOC
関数を使って確保され,_mp_d
分の領域が確保されます。再割り当てが不要な程度に十分な領域が確保されます(予測不能な事態が起きないようにするため)。
_mp_size
と_mp_alloc
はint
型,対して,mp_size_t
は常にlong
型になります。ある種の64bitシステム上では32bit長となるので,十分な幅を確保しつつ,数バイトはデータ領域を節約できます。