您是否可以对数据类型的最小大小做出任何假设?
到目前为止我读过的内容:
浮???双???
float.h
和limits.h
系统中的值是否相关?
答案 0 :(得分:30)
short int
不得大于int
int
不得大于long int
。
short int
长度必须至少为16位int
长度必须至少为16位long int
长度必须至少为32位long long int
必须至少为64位长。该标准不要求任何这些尺寸必然不同。例如,如果所有四种类型都是64位长,那么它是完全有效的。
答案 1 :(得分:11)
是的,float.h
和limits.h
中的值取决于系统。你永远不应该假设类型的宽度,但标准确实规定了一些最小值。见C99 standard中的§6.2.5和§5.2.4.2.1。
例如,标准仅表示char
应足够大以容纳执行字符集中的每个字符。它没有说它有多宽。
对于浮点情况,标准提示按照给出类型宽度的顺序:
有三种真实浮动类型,指定为浮动,双和长 双即可。 32) float 类型的值集是 double 类型的值集的子集; double 类型的值集合是 long double 类型的值集的子集。
他们隐含地定义哪个比另一个宽,但没有具体说明它们有多宽。 “子集”本身含糊不清,因为long double
可以具有完全相同的double
范围并满足此条款。
这是C的典型代表,并且每个环境都有很多。你不能假设,你必须问编译器。
答案 2 :(得分:5)
但是,新的C99指定(stdint.h
)个可选类型的最小尺寸,例如uint_least8_t
,int_least32_t
等等。
(见en_wikipedia_Stdint_h)
答案 3 :(得分:5)
九年来,对于float, double, long double
的最小大小,仍然没有直接答案。
C语言中的类型是否保证最小尺寸?
对于浮点类型...
从实用的角度来看,float
的最小大小为 32位,而double
的最小大小为 64位。 C允许double
和long 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 int
,int
和long 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
SCHAR_MIN -127
// - (2 7 - 1)SCHAR_MAX +127
// 2 7 - 1 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而不是标准类型。