C中类型的任何保证最小尺寸?

时间:2009-11-15 19:42:24

标签: c types cross-platform

您是否可以对数据类型的最小大小做出任何假设?

到目前为止我读过的内容:

  • char:1 Byte
  • 短:2字节
  • int:2个字节,通常为4个字节
  • long:4 Byte

浮???双???

float.hlimits.h系统中的值是否相关?

9 个答案:

答案 0 :(得分:30)

Wikipedia article

中介绍了这一点
  

short int不得大于int   int不得大于long int

     

short int长度必须至少为16位   int长度必须至少为16位   long int长度必须至少为32位   long long int必须至少为64位长。

     

该标准不要求任何这些尺寸必然不同。例如,如果所有四种类型都是64位长,那么它是完全有效的。

答案 1 :(得分:11)

是的,float.hlimits.h中的值取决于系统。你永远不应该假设类型的宽度,但标准确实规定了一些最小值。见C99 standard中的§6.2.5和§5.2.4.2.1。

例如,标准仅表示char应足够大以容纳执行字符集中的每个字符。它没有说它有多宽。

对于浮点情况,标准提示按照给出类型宽度的顺序:

§6.2.5.10

  

有三种真实浮动类型,指定为浮动长   双即可。 32) float 类型的值集是 double 类型的值集的子集; double 类型的值集合是 long double 类型的值集的子集。

他们隐含地定义哪个比另一个宽,但没有具体说明它们有多宽。 “子集”本身含糊不清,因为long double可以具有完全相同的double范围并满足此条款。

这是C的典型代表,并且每个环境都有很多。你不能假设,你必须问编译器。

答案 2 :(得分:5)

但是,新的C99指定(stdint.h)个可选类型的最小尺寸,例如uint_least8_tint_least32_t等等。
(见en_wikipedia_Stdint_h

答案 3 :(得分:5)

九年来,对于float, double, long double最小大小,仍然没有直接答案。


  

C语言中的类型是否保证最小尺寸?

对于浮点类型...

从实用的角度来看,float的最小大小为 32位,而double的最小大小为 64位。 C允许doublelong double共享相似的特征,因此long double可以和double一样小。 Example 1

我可以想象可能存在C兼容的48位double,但一无所知。


现在,让我们想象一下我们有钱的叔叔去世了,并留下了一笔财富来为 www.smallest_C_float.com 的发展和文化促进付出代价。

C指定:

1)float的有限范围至少为[1E-37…1E + 37]。参见FLT_MIN, FLT_MAX

2)(1.0f + FLT_EPSILON) – 1.0f <= 1E-5

3)float支持正值和负值。

Let X: Digit 1-9
Let Y: Digit 0-9
Let E: value -37 to 36
Let S: + or -
Let b: 0 or 1

我们的float可以以10为底的SX.YYYYY*10^E最小表示所有组合。

还需要

0.0±1E+37(另外3个)。我们不需要-0.0,次法线,±无限,也不需要非数字。

这是2 * 9 * 10 ^ 5 * 74 + 3个组合或133,200,003,至少需要27位才能进行编码-莫名其妙地。回想一下目标是最小尺寸。

使用经典的以2为底的方法,我们可以假设隐式1并得到 S1.bbbb_bbbb_bbbb_bbbb_b * 2 ^ e或2 * 2 ^ 17 * 226组合或26位。

如果尝试以16为基数,则大约需要2 * 15 * 16 ^(4或5)* 57个组合或至少26至30位。

结论:C float至少需要26位编码。


C的double不必表示比float大的指数范围,它仅具有不同的最低精度要求。 1E-9

S1.bbbb_bbbb_bbbb_bbbb_ bbbb_ bbbb_ bbbb_bb * 2 ^ e-> 2 * 2 ^ 30 * 226组合或39位。


在我们的想象一下计算机上,我们可以有一个13位的char,因此可以对float, double, long double进行编码而无需填充。这样我们就可以实现非填充的26位float和39位double, long double


1 Microsoft Visual C++ for x86, which makes long double a synonym for double

答案 4 :(得分:3)

通常开发人员提出这类问题时,正在处理排列打包struct以匹配已定义的内存布局(如消息协议)。假设该语言应直接指定为此目的布置16,24,32位等字段。

对于汇编语言和与特定CPU架构密切相关的其他特定于应用程序的语言来说,这是常规和可接受的,但有时候通用语言中的问题可能针对谁知道什么样的架构。< / p>

实际上,C语言并非用于特定的硬件实现。它通常被指定,因此C编译器实现者可以适当地适应特定CPU的现实。由9位字节,54位字和72位存储器地址组成的Frankenstein硬件架构可轻松无误地映射到C特征。 (char为9位; short intintlong int为54位。)

这种一般性是C规范说“不要太多关于sizeof(char)之外的int的大小&lt; = sizeof(short int)&lt; = sizeof(int)&lt; = sizeof(long int)。“这意味着字符的长度可以与长字相同!

当前的现实是 - 并且未来似乎成立 - 软件需要架构提供8位字节,并且存储器字可以作为单独的字节寻址。情况并非如此。不久前,我参与了CDC网络架构,该架构具有6位“字节”和60位字。这方面的C实现会很有趣。事实上,该架构负责Pascal的奇怪打包语义 - 如果有人记得那么。

答案 5 :(得分:3)

如果你不想检查你的系统/平台上任何类型的大小(以字符的倍数表示)确实是你期望的大小,你可以这样做:

enum CHECK_FLOAT_IS_4_CHARS
{
   IF_THIS_FAILS_FLOAT_IS_NOT_4_CHARS = 1/(sizeof(float) == 4)
};

答案 6 :(得分:2)

C99 N1256标准草案

http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

C99指定两种类型的整数保证:

  • 最小尺寸保证
  • 类型之间的相对大小

相对保证

6.2.5类型

  

8对于具有相同签名和不同整数转换等级的任何两个整数类型   (见6.3.1.1),具有较小整数转换等级的类型的值范围是a   另一种类型的值的子范围。

6.3.1.1布尔,字符和整数确定相对转换排名:

  

1每个整数类型都有一个整数转换等级,定义如下:

     
      
  • long long int的等级应大于long int的等级,即   应大于int的等级,其应大于short的等级   int,应大于signed char的等级。
  •   
  • 任何无符号整数类型的等级应等于相应的等级   有符号整数类型,如果有的话。
  •   
  • 对于所有整数类型T1,T2和T3,如果T1的等级大于T2且T2具有   比T3更高的排名,那么T1的排名高于T3
  •   

绝对最小尺寸

https://stackoverflow.com/a/1738587/895245提及,以下是为方便起见的引用。

5.2.4.2.1整数类型的大小<limits.h>

  

1 [...]它们的实现定义值的大小(绝对值)应等于或大于[...]

     
      
  • UCHAR_MAX 255 // 2 8 - 1
  •   
  • USHRT_MAX 65535 // 2 16 - 1
  •   
  • UINT_MAX 65535 // 2 16 - 1
  •   
  • ULONG_MAX 4294967295 // 2 32 - 1
  •   
  • ULLONG_MAX 18446744073709551615 // 2 64 - 1
  •   

浮点

如果定义了__STDC_IEC_559__宏,则保证每种C类型的IEEE类型,尽管long double有几种可能性:Is it safe to assume floating point is represented using IEEE754 floats in C?

答案 7 :(得分:1)

引用标准确实会将定义为“正确答案”,但实际上并不反映程序的编写方式。

人们一直假设char为8位,short为16,int为32,long为32或64,long long为64.

这些假设并不是一个好主意,但你不会因为制造它们而被解雇。

理论上,<stdint.h>可用于指定固定位宽类型,但您必须为Microsoft查找一个。 (See here for a MS stdint.h。)其中一个问题是C ++在技术上只需要C89兼容性就可以成为一个符合要求的实现;即使是普通的C,即使在2009年,C99也得不到完全支持。

char没有宽度规格也不准确。有,标准只是避免说是否签名。这是C99实际上说的:

  • 不是比特字段(字节)的最小对象的比特数
    CHAR_BIT 8
  • signed char类型对象的最小值 SCHAR_MIN -127 // - (2 7 - 1)
  • signed char类型对象的最大值 SCHAR_MAX +127 // 2 7 - 1
  • unsigned char类型对象的最大值 UCHAR_MAX 255 // 2 8 - 1

答案 8 :(得分:0)

大多数库定义如下:

#ifdef MY_ARCHITECTURE_1
typedef unsigned char u_int8_t;
typedef short int16_t;
typedef unsigned short u_int16_t;
typedef int int32_t;
typedef unsigned int u_int32_t;
typedef unsigned char u_char;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned short u_short;
#endif

然后,您可以在程序中使用这些typedef而不是标准类型。