Next: , Previous: , Up: Internals   [Index]


16.1 整数型の内部構造

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_allocint型,対して,mp_size_tは常にlong型になります。ある種の64bitシステム上では32bit長となるので,十分な幅を確保しつつ,数バイトはデータ領域を節約できます。