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、および long long です。

表 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-4   long の表現 (Intel、SPARC v8、SPARC v9)  
ビット 内容
24 - 31
バイト 0 (SPARC) v8
バイト 4 (SPARC) v9
バイト 3 (Intel)
16 - 23
バイト 1 (SPARC) v8
バイト 5 (SPARC) v9
バイト 2 (Intel)
8 - 15
バイト 2 (SPARC) v8
バイト 6 (SPARC) v9
バイト 1 (Intel)
0 - 7
バイト 3 (SPARC) v8
バイト 7 (SPARC) v9
バイト 0 (Intel)


表 A-5   long long1 の表現  
ビット 内容
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、long double のデータ要素は、ANSI/ISO IEEE 754-1985 規格に従って下の式のように表現されます。

         (-1)s2(e - bias) ¥ j.f

詳細については、『数値計算ガイド』を参照してください。

極値表現

正規化された float と double の数は「隠された」ビットまたは暗黙のビットを持つと言われます。それにより、精度を 1 ビット分高めることができます。
long double の場合は、先行ビットは暗黙的 (SPARC) または明示的 (x86) のいずれかになります。このビットは正規数に対しては 1、非正規数に対しては 0 になります。

表 A-10   float の表現
正規数
(0<e<255):
非正規数
(e=0, f!=0):
ゼロ (e=0, f=0):
シグナルを発生する NaN s=u, e=255(最大値); f=.0uuu〜uu (少なくとも 1 ビットは 0 以外)
シグナルを発生しない NaN s=u, e=255(最大値); f=.1uuu〜uu
無限大 s=u, e=255(最大値); f=.0000〜00 (すべてが 0)


表 A-11   double の表現  
正規数
(0<e<2047):
非正規数
(e=0, f!=0):
ゼロ (e=0, f=0):
シグナルを発生する NaN s=u, e=2047(最大値); f=.0uuu〜uu (少なくとも 1 ビットは 0 以外)
シグナルを発生しない NaN s=u, e=2047(最大値); f=.1uuu〜uu
無限大 s=u, e=2047(最大値); f=.0000〜00 (すべてが 0)


表 A-12   long double の表現
正規数
(0<e<32767):
非正規数
(e=0, f!=0):
ゼロ (e=0, f=0):
シグナルを発生する NaN s=u, e=32767(最大値); f=1.0uuu〜uu (少なくとも 1 ビットは 0 以外)
シグナルを発生しない NaN s=u, e=32767(最大値); f=1.1uuu〜uu
無限大 s=u, e=32767(最大値); f=1.0000〜00 (すべてが 0)


重要な数の 16 進数表現

よく使用される数値の16 進数表現を次の表にまとめます。

表 A-13   重要な数の 16 進数表現 (SPARC)

値

float 型

double 型

long double 型

+0
-0
00000000
80000000
0000000000000000
8000000000000000
00000000000000000000000000000000
80000000000000000000000000000000
+1.0
-1.0
3F800000
BF800000
3FF0000000000000
BFF0000000000000
3FFF00000000000000000000000000000
BFFF00000000000000000000000000000
+2.0
+3.0
40000000
40400000
4000000000000000
4008000000000000
40000000000000000000000000000000
40080000000000000000000000000000
+無限
-無限
7F800000
FF800000
7FF0000000000000
FFF0000000000000
7FFF00000000000000000000000000000
FFFF00000000000000000000000000000
NaN 7FBFFFFF 7FF7FFFFFFFFFFFF 7FFF7FFFFFFFFFFFFFFFFFFFFFFFFFFF


表 A-14   重要な数の 16 進数表現 (x86)

値

float 型

double 型

long double 型

+0
-0
00000000
80000000
0000000000000000
0000000080000000
00000000000000000000
80000000000000000000
+1.0
-1.0
3F800000
BF800000
000000003FF00000
00000000BFF00000
3FFF8000000000000000
BFFF8000000000000000
+2.0
+3.0
40000000
40400000
0000000040000000
0000000040080000
40008000000000000000
4000C000000000000000
+無限
-無限
7F800000
FF800000
000000007FF00000
00000000FFF00000
7FFF8000000000000000
FFFF8000000000000000
NaN 7FBFFFFF FFFFFFFF7FF7FFFF 7FFFBFFFFFFFFFFFFFFF


詳細については、『数値計算ガイド』を参照してください。

ポインタ表現

C 言語におけるポインタは 4 バイトを使用します。NULL 値のポインタはゼロと等価です。

配列の格納

配列は、それぞれの要素が決められた記憶順序で格納されます。各要素は実際には記憶要素の一次元の列に格納されます。

C 言語の配列は行の並びを優先して格納されます。この順序では、多次元配列における右端の添字が最も速く変化します。

文字列データ型は char 要素の配列になります。連結後、文字列リテラルまたはワイド文字列リテラルに指定できる最大の文字数は、4,294,967,295 個です。

表 A-15   自動配列の型と最大の大きさ 
型 SPARC および Intel の最大要素数 SPARC V9 の最大要素数
char
4,294,967,295 2,305,843,009,213,693,951
short 2,147,483,647 1,152,921,504,606,846,975
int 1,073,741,823 576,460,752,303,423,487
long 1,073,741,823 288,230,376,151,711,743
float 1,073,741,823 576,460,752,303,423,487
double 536,870,911 288,230,376,151,711,743
long double 268,435,451 144,115,188,075,855,871
long long1 536,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 における引数の渡し方について説明します。

C の関数への引数は、すべて値渡しされます。

実引数は関数の宣言において宣言されるのと逆の順序で渡されます。

実引数が式の場合、関数参照の前に評価されます。その後、式の結果がレジスタに置かれるかスタックにプッシュされます。

(SPARC)

関数は integer 型の結果をレジスタ %o0 に返します。float 型の結果はレジスタ
%f0 に、double 型の結果はレジスタ %f0 と %f1 に返します。
long long 型1 整数は上位ワードは %oN、下位ワードは %o (N+1) というようにレジスタに渡されます。レジスタ内の結果は同様の順序で %i0 と %i1 に返されます。
double および long double 型を除くすべての引数は 4 バイトの値として渡されます。double 型は 8 バイトの値として渡されます。先頭 6 個の 4 バイト値 (double を 8 と数える) は %o0 から %o5 までのレジスタに渡され、残りはスタック経由で渡されます。構造体の場合は、構造体のコピーが作成され、ポインタがそのコピーに渡されます。long double は構造体と同様に渡されます。
関数から戻った後、スタックから引数をポップするのは呼び出し側の責任です。上記のレジスタは、呼び出し側から見えます。

(x86)

関数は integer 型の結果をレジスタ %eax に返します。
long long の結果はレジスタ %edx と %eax に返されます。float、double、
long
double 型の結果はレジスタ %st(0) に返されます。
struct、union、long long、double、long double を除くすべての引数は 4 バイト値として渡されます。long long は 8 バイト値として、また long double は 12 バイト値としてそれぞれ渡されます。
struct と union はスタックにコピーされます。サイズは 4 の倍数バイトに丸められます。struct と union を返す関数は、その struct や union を格納する場所を指す隠された最初の引数に渡されます。
関数から戻った後、スタックから引数をポップするのは呼び出し側の責任です (呼び出された関数によってポップされる struct や union の余分な引数を除く)。
1 -Xc モードでは使用できません。


サン・マイクロシステムズ株式会社
Copyright information. All rights reserved.
ホーム   |   目次   |   前ページへ   |   次ページへ   |   索引