Sun Studio 12:C 用户指南

附录 F ISO C 数据表示法

本附录描述 ISO C 如何表示存储器中的数据以及向函数传递参数的机制。其目的是为想要编写或使用非 C 语言模块并将这些模块与 C 代码连接的程序员提供指导。

F.1 存储分配

下表显示了数据类型及其表示方法。


注 –

栈中分配的存储空间(带有内部、自动或链接的标识符)应限于 2G 字节或更少。


表 F–1 数据类型的存储分配

数据类型 

内部表示 

char 元素

单个 8 位字节,在单字节边界上对齐。 

short 整数

半字(二字节或 16 位),在双字节边界上对齐 

int

32 位(四字节或一个字),在四字节边界上对齐 

long

在 v8 和 x86 上为 32 位(四字节或一个字),在四字节边界上对齐 

在 v9 上为 64 位(八字节或两个字),在八字节边界上对齐 

pointer

在 v8 和 x86 上为 32 位(四字节或一个字),在四字节边界上对齐 

在 v9 上为 64 位(八字节或两个字),在八字节边界上对齐 

long long [如果设置 -xc99=nonelong long-Xc 模式下不可用。]

(SPARC) 64 位(八字节或两个字),在八字节边界上对齐 

(x86) 64 位(八字节或两个字),在四字节边界上对齐

float

32 位(四字节或一个字),在四字节边界上对齐。一个 float 元素包含一个 sign 位、一个 8 位指数和一个 23 位尾数。

double

64 位(八字节或两个字),在八字节边界上对齐 (SPARC) 或在四字节边界上对齐 (x86)。一个 double 元素包含一个 sign 位、一个 11 位指数和一个 52 位尾数。

long double

v8 (SPARC) 128 位(16 字节或四个字),在八字节边界上对齐。一个 long double 元素包含一个 sign 位、一个 15 位指数和一个 112 位尾数。

v9 (SPARC) 128 位(16 字节或四个字),在 16 字节边界上对齐。一个 long double 元素包含一个 sign 位、一个 15 位指数和一个 112 位尾数。

(x86) 96 位(12 字节或三个字),在四字节边界上对齐。一个 long double 元素包含一个 sign 位、一个 16 位指数和一个 64 位尾数。16 位未使用。

F.2 数据表示法

任何给定数据元素的位编号取决于使用的体系结构:SPARC 工作站TM机器将位 0 用作最低有效位,将字节 0 用作最高有效字节。本节中的表描述各种表示法。

F.2.1 整数表示法

ISO C 中使用的整型有 shortintlonglong long

表 F–2 short 的表示法

位 

内容 

8- 15 

字节 0 (SPARC) 

字节 1 (x86)

0- 7 

字节 1 (SPARC) 

字节 0 (x86) 

表 F–3 int 的表示法

位 

内容 

24- 31 

字节 0 (SPARC) 

字节 3 (x86) 

16- 23 

字节 1 (SPARC) 

字节 2 (x86) 

8- 15 

字节 2 (SPARC) 

字节 1 (x86) 

0- 7 

字节 3 (SPARC) 

字节 0 (x86) 

表 F–4 在 x86 和 SPARC v8 与 SPARC v9 中 long 的表示法

位 

内容 

24- 31 

字节 0 (SPARC) v8 

字节 4 (SPARC) v9 

字节 3 (x86) 

16- 23 

字节 1 (SPARC) v8 

字节 5 (SPARC) v9 

字节 2 (x86)

8- 15 

字节 2 (SPARC) v8 

字节 6 (SPARC) v9 

字节 1 (x86)

0- 7 

字节 3 (SPARC) v8 

字节 7 (SPARC) v9 

字节 0 (x86)


注 –

long long-Xc 模式下不可用。


表 F–5 long long 的表示法

位 

内容 

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) 

F.2.2 浮点表示法

floatdoublelong double 数据元素按照 ISO IEEE 754-1985 标准来表示。表示为:

(-1)s(e- bias)¥2 j.f

其中:

下表显示各个位的位置。

表 F–6 float 表示法

位 

名称 

31 

符号 

23- 30 

指数 

0- 22 

尾数部分 

表 F–7 double 表示法

位 

名称 

63 

符号 

52- 62 

指数 

0- 51 

尾数部分 

表 F–8 long double 表示法 (SPARC)

位 

名称 

127 

符号 

112- 126 

指数 

0- 111 

尾数部分 

表 F–9 long double 表示法 (x86)

位 

名称 

80- 95 

未使用 

79 

符号 

64- 78 

指数 

63 

前导位 

0- 62 

尾数部分 

有关详细信息,请参阅《数值计算指南》。

F.2.3 异常值

floatdouble 数被认为包含一个“隐藏的”或隐含的位,从而比不包含该位时的精度高一位。对于 long double,前导位为隐式 (SPARC) 或显式 (x86);该位对于正规数为 1,对于非正规数为 0。

表 F–10 float 表示法

正规数 (0<e<255): 

(-1)符号2 (指数- 127)1.f

非正规数 

(e=0, f!=0): 

(-1)符号2 (-126)0.f

零 (e=0, f=0): 

(-1)符号0.0

信号 NaN 

s=u,e=255(max);f=.0uuu-uu;至少一个位必须为非零 

静态 NaN 

s=u,e=255(max);f=.1uuu-uu 

无穷 

s=u,e=255(max);f=.0000-00(全为零) 

表 F–11 double 表示法

正规数 (0<e<2047): 

(-1)符号2 (指数- 1023)1.f

非正规数 (e=0, f!=0): 

(-1)符号2 (-1022)0.f

零 (e=0, f=0): 

(-1)符号0.0

信号 NaN 

s=u,e=2047(max);f=.0uuu-uu;至少一个位必须为非零 

静态 NaN 

s=u,e=2047(max);f=.1uuu-uu 

无穷 

s=u,e=2047(max);f=.0000-00(全为零) 

表 F–12 long double 表示法

正规数 (0<e<32767): 

(-1)符号2 (指数- 16383)1.f

非正规数 (e=0, f!=0): 

(-1)符号2 (-16382)0.f

零 (e=0, f=0): 

(-1)符号0.0

信号 NaN 

s=u,e=32767(max);f=.0uuu-uu;至少一个位必须为非零 

静态 NaN 

s=u,e=32767(max);f=.1uuu-uu 

无穷 

s=u,e=32767(max);f=.0000-00(全为零) 

F.2.4 选定的数的十六进制表示

下表显示十六进制表示。

表 F–13 选定数的十六进制表示法 (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 

表 F–14 选定数的十六进制表示法 (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 

有关详细信息,请参阅《数值计算指南》。

F.2.5 指针表示

C 中的一个指针占 4 个字节。C 中的一个指针在 SPARC v9 体系结构中占 8 个字节。NULL 值指针等于零。

F.2.6 数组存储

数组及其元素按特定的存储顺序存储。元素实际上按存储元素的线性序存储。

C 数组按以行优先的方式存储;多维数组中的最后一个下标变化最快。

字符串数据类型是 char 元素的数组。字符串文字或宽字符串文字(并置后)中允许的字符数最大值为 4,294,967,295。

有关栈中存储分配大小限制的信息,请参见F.1 存储分配

表 F–15 数组类型和存储

类型 

SPARC 和 x86 上的元素数最大值 

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 long [当设置 -xc99=none 时,在 -Xc 模式下无效。]

536,870,911 

288,230,376,151,711,743 

静态数据和全局数组可以容纳更多元素。

F.2.7 异常值的算术运算

本节介绍了对异常和普通浮点值的组合应用基本算术运算所得的结果。以下信息假定不执行陷阱或任何其他异常操作。

下表解释缩写:

表 F–16 缩写用法

缩写 

含义 

Num 

非正规数或正规数 

Inf 

无穷(正或负) 

NaN 

不是数 

Uno 

无序 

下表描述对不同类型的操作数的组合执行算术运算所得值的类型。

表 F–17 加法和减法结果

 

右操作数:0 

右操作数:Num 

右操作数:Inf 

右操作数:NaN 

左操作数:0 

Num 

Inf 

NaN 

左操作数:Num 

Num 

请参见 [结果太大(溢出)时,Num + Num 可能为 Inf 而不是 Num。无穷值具有相反的 sign 时,Inf + Inf = NaN。]

Inf 

NaN 

左操作数:Inf 

Inf 

Inf 

请参见

NaN 

左操作数:NaN 

NaN 

NaN 

NaN 

NaN 

表 F–18 乘法结果

 

右操作数:0 

右操作数:Num 

右操作数:Inf 

右操作数:NaN 

左操作数:0 

NaN 

NaN 

左操作数:Num 

Num 

Inf 

NaN 

左操作数:Inf 

NaN 

Inf 

Inf 

NaN 

左操作数:NaN 

NaN 

NaN 

NaN 

NaN 

表 F–19 除法结果

 

右操作数:0 

右操作数:Num 

右操作数:Inf 

右操作数:NaN 

左操作数:0 

NaN 

NaN 

左操作数:Num 

Inf 

Num 

NaN 

左操作数:Inf 

Inf 

Inf 

NaN 

NaN 

左操作数:NaN 

NaN 

NaN 

NaN 

NaN 

表 F–20 比较结果

 

右操作数:0 

右操作数:+Num 

右操作数:+Inf 

右操作数:+NaN 

左操作数:0 

Uno 

左操作数:+Num 

比较的结果 

Uno 

左操作数:+Inf 

Uno 

左操作数:+NaN 

Uno 

Uno 

Uno 

Uno 


注 –

NaN 与 NaN 比较结果为无序,从而导致不相等。+0 与 - 0 的比较结果是相等。


F.3 参数传递机制

本节描述在 ISO C 中如何传递参数。

F.3.1 32 位 SPARC

函数在寄存器 %o0 中返回 integer 结果,在寄存器 %f0 中返回 float 结果,在寄存器 %f0%f1 中返回 double 结果。

long long 整数以较高词序在 %oN 寄存器中进行传递,以较低词序在 %o(N+1) 寄存器中进行传递。寄存器中的结果在 %o0%o1 中返回,排序相似。

doubles 和 long double 外,所有参数都作为四字节值来传递。double 作为八字节值传递。前六个四字节值(double 计为 8)在寄存器 %o0%o5 中传递。其余值传递到栈中。结构的传递方式是复制结构并将指针传递到副本。long double 的传递方式与结构的传递方式相同。

此处描述的寄存器是可被调用程序识别的寄存器。

F.3.1.1 64 位 SPARC

所有整型参数均作为 8 字节值传递。

浮点参数尽可能在浮点寄存器中传递。

(x86)

函数在以下寄存器中返回结果:

表 F–21 x86 函数返回类型所使用的寄存器

寄存器 

返回的类型 

int 

%eax 

long long

%edx%eax

floatdoublelong double

%st(0)

float _Complex

实部为 %eax,虚部为 %edx

double _Complexlong double _Complex

与包含相应浮点类型的两个元素的结构相同。 

除了 structunionlong longdoublelong double 之外的所有参数都作为四字节值传递;long long 作为八字节值传递,double 作为八字节值传递,long double 作为 12 字节值传递。

structunion 被复制到栈中。大小向上舍入为 4 字节的倍数。返回 structunion 的函数被传递一个隐藏的首参数,并指向返回的 structunion 的存储位置。

从一个函数返回时,需要调用程序从栈中弹出参数,但 structunion 返回的附加参数除外,它由调用的函数弹出。