| C ユーザーズガイド |
付録 A
ANSI C データ表現
この付録では、ANSI C の記憶装置におけるデータ表現と、関数に引数を渡す仕組みについて説明します。本章は、C 言語以外の言語でモジュールを記述したり使用したい場合に、これらのモジュールに C 言語コードへのインタフェースを持たせるための手引きとして書かれたものです。説明項目は次のとおりです。
記憶装置の割り当て
データ型とその表現方法について表 A-1 にまとめます。
表 A-1 データ型に対する記憶装置の割り当て char型要素8 ビット幅のシングルバイト。1 バイトで境界整列される。 short型整数ハーフワード (2 バイト、つまり 16 ビット)。2 バイトで境界
整列される。int型v8 の 32 ビット (4 バイト、つまり 1 ワード)。4 バイトで境界整列される。 long型v8 の 32 ビット (4 バイト、つまり 1 ワード)。4 バイトで境界整列される。
v9 では 64 ビット (4 バイト、つまり 1 ワード)。8 バイト境界で整列される。long long型1(SPARC) 64 ビット (8 バイト、つまり 2 ワード)。
ダブルワードで境界整列される。
(x86) 64 ビット (8 バイト、つまり 2 ワード)。4 バイトで境界整列される。float型32 ビット (4 バイト、つまり 1 ワード)。4 バイトで境界整列される。1 ビットの符号、8 ビットの指数部および 23 ビットの仮数部から成る。 double型64 ビット (8 バイト、つまり 2 ワード)。
(SPARC) 8 バイトで境界整列される。
(x86) 4 バイト境界に割り当てられる。
1 ビットの符号、11 ビットの指数部、52 ビットの仮数部から成る。long double型v8 (SPARC) 128 ビット (16 バイト、つまり 4 ワード)。8 バイトで境界整列される。1 ビットの符号、15 ビットの指数部および 112 ビットの仮数部から成る。
v9 (SPARC) 128 ビット (16 バイト、つまり 4 ワード)。16 バイトで境界整列される。1 ビットの符号、15 ビットの指数部および 112 ビットの仮数部から成る。
(x86) 96 ビット (12 バイト、つまり 3 ワード)。4 バイトで境界整列される。1 ビットの符号、16 ビットの指数部および 64 ビットの仮数部から成る。16 ビットは使用されない。
1 long long は -Xc モードでは使用できません。
データ表現
使用しているアーキテクチャによってデータ要素のビット番号の割り当てが異なります。SPARCstation` ではビット 0 を最下位有効ビット、バイト 0 を最上位有効バイトとしてそれぞれ使用します。以下の表に表現方法を示します。
整数表現
ANSI C で使用されている整数型は
short、int、long、およびlonglongです。
表 A-2 shortの表現 (x86) 8 - 15バイト 0 (SPARC)
バイト 1 (x86) 0 - 7バイト 1 (SPARC)
バイト 0 (x86)
表 A-3 intとlongの表現 24 - 31バイト 0 (SPARC)
バイト 3 (x86) 16 - 23バイト 1 (SPARC)
バイト 2 (x86) 8 - 15バイト 2 (SPARC)
バイト 1 (x86) 0 - 7バイト 3 (SPARC)
バイト 0 (x86)
表 A-5 longlong1 の表現 56 - 63バイト 0 (SPARC)
バイト 7 (x86) 48 - 55バイト 1 (SPARC)
バイト 6 (x86) 40 - 47バイト 2 (SPARC)
バイト 5 (x86) 32 - 39バイト 3 (SPARC)
バイト 4 (x86) 24 - 31バイト 4 (SPARC)
バイト 3 (x86) 16 - 23バイト 5 (SPARC)
バイト 2 (x86) 8 - 15バイト 6 (SPARC)
バイト 1 (x86) 0 - 7バイト 7 (SPARC)
バイト 0 (x86)
1 long long は -Xc モードでは使用できません。
浮動小数点表現
float、double、longdoubleのデータ要素は、ANSI/ISO IEEE 754-1985 規格に従って下の式のように表現されます。
- s = 符号
- e = バイアス付きの指数
- j = 先行ビット。e の値によって決まる。
longdouble(x86) では、先行ビットは明示的。その他の場合は暗黙的。- f = 仮数部 (23 ビット)
- u = ビットが 0 または 1 を示す。
表 A-6 floatの表現31 符号 (Sign) 23 - 30 指数部 (Exponent) 0 - 22 仮数部 (Fraction)
表 A-7 doubleの表現63 符号 (Sign) 52 - 62 指数部 (Exponent) 0 - 51 仮数部 (Fraction)
表 A-8 longdoubleの表現 (SPARC)127 符号 (Sign) 112 - 126 指数部 (Exponent) 0 - 111 仮数部 (Fraction)
表 A-9 longdoubleの表現 (x86)81 - 95 使用せず 80 符号 (Sign) 64 - 79 指数部 (Exponent) 63 先行ビット 0 - 62 仮数部 (Fraction)
極値表現
正規化された
floatとdoubleの数は「隠された」ビットまたは暗黙のビットを持つと言われます。それにより、精度を 1 ビット分高めることができます。long doubleの場合は、先行ビットは暗黙的 (SPARC) または明示的 (x86) のいずれかになります。このビットは正規数に対しては 1、非正規数に対しては 0 になります。
重要な数の 16 進数表現
よく使用される数値の16 進数表現を次の表にまとめます。
ポインタ表現
C 言語におけるポインタは 4 バイトを使用します。
NULL値のポインタはゼロと等価です。配列の格納
配列は、それぞれの要素が決められた記憶順序で格納されます。各要素は実際には記憶要素の一次元の列に格納されます。
C 言語の配列は行の並びを優先して格納されます。この順序では、多次元配列における右端の添字が最も速く変化します。
文字列データ型は
char要素の配列になります。連結後、文字列リテラルまたはワイド文字列リテラルに指定できる最大の文字数は、4,294,967,295 個です。
表 A-15 自動配列の型と最大の大きさ char4,294,967,295 2,305,843,009,213,693,951 short2,147,483,647 1,152,921,504,606,846,975 int1,073,741,823 576,460,752,303,423,487 long1,073,741,823 288,230,376,151,711,743 float1,073,741,823 576,460,752,303,423,487 double536,870,911 288,230,376,151,711,743 long double268,435,451 144,115,188,075,855,871 long long1536,870,911 288,230,376,151,711,743
1 -Xcモードでは無効です。
静的および大域配列にはさらに多くの要素を格納することができます。
極値の算術演算
この節では、浮動小数点の極値と通常値を組み合わせたものに基本算術演算を適用して得られる結果について説明します。
表 A-16 略語の使用法 Num非正規のまたは正規化された数字 Inf無限大 (正または負) NaN数字ではない Uno順序不定
次の表は、異なるタイプのオペランドを組み合わせて行なった算術演算から得られた値のタイプを示しています。
表 A-17 加算と減算の結果 加算および減算 左のオペランド 右のオペランド 0 Num Inf NaN 0 0 Num Inf NaN Num Num 注を参照 Inf NaN Inf Inf Inf 注を参照 NaN NaN NaN NaN NaN NaN
注 - Num + Num は、結果 が 大きすぎる (オーバーフロー) と Num ではなく Inf になります。Inf + Inf は、無限大の符号が逆であれば NaN になります。
表 A-18 乗算結果 左のオペランド 右のオペランド 0 Num Inf NaN 0 0 0 NaN NaN Num 0 Num Inf NaN Inf NaN Inf Inf NaN NaN NaN NaN NaN NaN
表 A-19 除算結果 左のオペランド 右のオペランド 0 Num Inf NaN 0 NaN 0 0 NaN Num Inf Num 0 NaN Inf Inf Inf NaN NaN NaN NaN NaN NaN NaN
表 A-20 比較結果 左のオペランド 右のオペランド 0 +Num +Inf NaN 0 = < < Uno +Num > 比較結果 < Uno +Inf > > = Uno NaN Uno Uno Uno Uno
注 - NaN と比較した NaN は順序不定で、結果は不等価になります。+0 は �0 と比較結果が等しくなります。
引数を渡す仕組み
本節では ANSI/ISO C における引数の渡し方について説明します。
実引数は関数の宣言において宣言されるのと逆の順序で渡されます。
実引数が式の場合、関数参照の前に評価されます。その後、式の結果がレジスタに置かれるかスタックにプッシュされます。
- 関数は
integer型の結果をレジスタ%o0に返します。float型の結果はレジスタ%f0に、double型の結果はレジスタ%f0と%f1に返します。
longlong型1 整数は上位ワードは%oN、下位ワードは%o(N+1)というようにレジスタに渡されます。レジスタ内の結果は同様の順序で%i0と%i1に返されます。doubleおよびlongdouble型を除くすべての引数は 4 バイトの値として渡されます。double型は 8 バイトの値として渡されます。先頭 6 個の 4 バイト値 (doubleを 8 と数える) は%o0から%o5までのレジスタに渡され、残りはスタック経由で渡されます。構造体の場合は、構造体のコピーが作成され、ポインタがそのコピーに渡されます。longdoubleは構造体と同様に渡されます。- 関数から戻った後、スタックから引数をポップするのは呼び出し側の責任です。上記のレジスタは、呼び出し側から見えます。
- 関数は
integer型の結果をレジスタ%eaxに返します。1 -Xc モードでは使用できません。
longlongの結果はレジスタ%edxと%eaxに返されます。float、double、
longdouble型の結果はレジスタ%st(0)に返されます。struct、union、longlong、double、longdoubleを除くすべての引数は 4 バイト値として渡されます。longlongは 8 バイト値として、またlongdoubleは 12 バイト値としてそれぞれ渡されます。structとunionはスタックにコピーされます。サイズは 4 の倍数バイトに丸められます。structとunionを返す関数は、そのstructやunionを格納する場所を指す隠された最初の引数に渡されます。- 関数から戻った後、スタックから引数をポップするのは呼び出し側の責任です (呼び出された関数によってポップされる
structやunionの余分な引数を除く)。
|
サン・マイクロシステムズ株式会社 Copyright information. All rights reserved. |
ホーム | 目次 | 前ページへ | 次ページへ | 索引 |