C 中的类型有保证最小尺寸吗?
您通常可以对数据类型的最小大小做出任何假设吗?
到目前为止我读过的内容:
- char:1字节
- 短:2字节
- int:2字节,通常4字节
- 长:4字节
浮点???双倍的???
float.h
和 limits.h
中的值是否依赖于系统?
Can you generally make any assumptions about the minimum size of a data type?
What I have read so far:
- char: 1 Byte
- short: 2 Byte
- int: 2 Byte, typically 4 Byte
- long: 4 Byte
float??? double???
Are the values in float.h
and limits.h
system dependent?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
维基百科文章对此进行了介绍:
This is covered in the Wikipedia article:
是的,
float.h
和limits.h
中的值与系统相关。您永远不应该对类型的宽度做出假设,但标准确实规定了一些最小值。请参阅 C99 中的第 6.2.5 节和第 5.2.4.2.1 节标准。例如,标准仅规定
char
应足够大以容纳执行字符集中的每个字符。它没有说它有多宽。对于浮点情况,标准提示给出类型宽度的顺序:
§6.2.5.10
他们隐含地定义了哪个比另一个更宽,但没有具体定义它们有多宽。 “子集”本身是模糊的,因为
long double
可以具有与double
完全相同的范围并满足此子句。这是 C 语言的典型运行方式,每个单独的环境都有很多工作要做。你不能假设,你必须问编译器。
Yes, the values in
float.h
andlimits.h
are system dependent. You should never make assumptions about the width of a type, but the standard does lay down some minimums. See §6.2.5 and §5.2.4.2.1 in the C99 standard.For example, the standard only says that a
char
should be large enough to hold every character in the execution character set. It doesn't say how wide it is.For the floating-point case, the standard hints at the order in which the widths of the types are given:
§6.2.5.10
They implicitly defined which is wider than the other, but not specifically how wide they are. "Subset" itself is vague, because a
long double
can have the exact same range of adouble
and satisfy this clause.This is pretty typical of how C goes, and a lot is left to each individual environment. You can't assume, you have to ask the compiler.
九年了,仍然没有关于
float、double、long double
的最小大小的直接答案。对于浮点类型...
从实用的角度来看,
float
最小大小为32位 和double
是 64 位。 C 允许double
和long double
具有相似的特征,因此long double
可以和double
一样小:示例1或80位或128位或者...我可以想象一个符合 C 标准的 48 位
double
可能已经存在 - 但不知道有什么。现在,让我们想象一下,我们富有的叔叔去世了,给我们留下了一笔财富,用于支付www.smallest_C_float.com的开发和文化推广。
C 指定:
float
有限范围至少为 [1E-37…1E+37]。请参阅FLT_MIN、FLT_MAX
(1.0f + FLT_EPSILON) – 1.0f <= 1E-5
。float
支持正值和负值。设 X:数字 1-9
设 Y:数字 0-9
令E:值-37到36
设 S:+ 或 -
设b:0或1
我们的
float
可以使用以 10 为基数的SX.YYYYY*10^E
最低限度地表示所有组合。还需要
0.0
和±1E+37
(另外 3 个)。我们不需要 -0.0、次正常值、±无穷大或非数字。即 2*9*105*74 + 3 个组合或 133,200,003,至少需要 27 位进行编码 - 不知何故。回想一下,目标是最小尺寸。
使用经典的基数为 2 的方法,我们可以假设隐含的 1 并得到
S1.bbbb_bbbb_bbbb_bbbb_b*2e 或 2*217*226 组合或 26 位。
如果我们尝试以 16 为基数,则需要大约 2*15*16(4 或 5)*57 个组合或至少 26 到 30 位。
结论:AC
float
至少需要 26 位编码。C 的
double
不需要表达比float
更大的指数范围,它仅具有不同的最小精度要求。1E-9
。S1.bbbb_bbbb_bbbb_bbbb_ bbbb_ bbbb_ bbbb_bb*2e --> 2*230*226 组合或 39 位。
在我们的想象一下计算机上,我们可以有一个 13 位
char
,因此可以对float、double、long double
进行编码,而无需填充。这样我们就可以实现一个非填充的26位float
和39位double, long double
。1:Microsoft Visual C++ for x86,它使
long double
double
的同义词[编辑] 2020
额外的
double
要求可能需要 41 位。可能必须使用 42 位double
和 28 位float
。需要复查。叔叔会不高兴的。Nine years and still no direct answer about the minimum size for
float, double, long double
.For floating point type ...
From a practical point-of-view,
float
minimum size is 32-bits anddouble
is 64- bits. C allowsdouble
andlong double
to share similar characteristics, so along double
could be as small as adouble
: Example1 or 80-bit or 128-bit or ...I could imagine a C compliant 48-bit
double
may have existed – yet do not know of any.Now, let us imagine our rich uncle dies and left us a fortune to pay for the development and cultural promotion for www.smallest_C_float.com.
C specifies:
float
finite range is at least [1E-37… 1E+37]. SeeFLT_MIN, FLT_MAX
(1.0f + FLT_EPSILON) – 1.0f <= 1E-5
.float
supports positive and negative values.Let X: Digit 1-9
Let Y: Digit 0-9
Let E: value -37 to 36
Let S: + or -
Let b: 0 or 1
Our
float
could minimally represent all the combinations, using base 10, ofSX.YYYYY*10^E
.0.0
and±1E+37
are also needed (3 more). We do not need -0.0, sub-normals, ±infinity nor not-a-numbers.That is 2*9*105*74 + 3 combinations or 133,200,003 which needs at least 27 bits to encode - somehow. Recall the goal is minimal size.
With a classic base 2 approach, we can assume an implied 1 and get
S1.bbbb_bbbb_bbbb_bbbb_b*2e or 2*217*226 combinations or 26 bits.
If we try base 16, we then need about 2*15*16(4 or 5)*57 combinations or at least 26 to 30 bits.
Conclusion: A C
float
needs at least 26 bits of encoding.A C’s
double
need not express a greater exponential range thanfloat
, it only has a different minimal precision requirement.1E-9
.S1.bbbb_bbbb_bbbb_bbbb_ bbbb_ bbbb_ bbbb_bb*2e --> 2*230*226 combinations or 39 bits.
On our imagine-if-you-will computer, we could have a 13-bit
char
and so encodefloat, double, long double
without padding. Thus we can realize a non-padded 26-bitfloat
and 39-bitdouble, long double
.1: Microsoft Visual C++ for x86, which makes
long double
a synonym fordouble
[Edit] 2020
Additional
double
requirements may require 41 bits. May have to use 42-bitdouble
and 28-bitfloat
. Will need to review. Uncle will not be happy.但是,新的 C99 指定(在 stdint.h 中)最小大小的可选类型,例如 uint_least8_t、int_least32_t 等。< br>
(参见en_wikipedia_Stdint_h)
However, the new C99 specifies (in
stdint.h
) optional types of minimal sizes, likeuint_least8_t
,int_least32_t
, and so on..(see en_wikipedia_Stdint_h)
如果您不想检查系统/平台上任何类型的大小(以字符的倍数为单位)是否确实是您期望的大小,您可以这样做:
If you wan't to check the size (in multiples of chars) of any type on your system/platform really is the size you expect, you could do:
通常,提出此类问题的开发人员正在处理排列打包结构以匹配定义的内存布局(对于消息协议)。假设该语言应直接指定布局 16 位、24 位、32 位等字段。
对于汇编语言和与特定 CPU 体系结构紧密相关的其他特定于应用程序的语言来说,这是常规的且可以接受的,但对于可能针对谁知道哪种体系结构的通用语言来说,有时会出现问题。
事实上,C 语言并不是为特定的硬件实现而设计的。它是一般性指定的,以便 C 编译器实现者可以正确地适应特定 CPU 的实际情况。由 9 位字节、54 位字和 72 位内存地址组成的弗兰肯斯坦硬件架构可以轻松且明确地映射到 C 功能。 (
char
为 9 位;short int
、int
和long int
为 54 位。)这种通用性是为什么 C 规范说了这样的话:“不要对超出 sizeof (char) <= sizeof (short int) <= sizeof (int) <= sizeof (long int) 的 int 大小抱有太多期望。 ”这意味着字符可以与长整型具有相同的大小!
当前的现实是——而且未来似乎也是如此——软件要求架构提供 8 位字节,并且内存字可作为单独的字节进行寻址。情况并非总是如此。不久前,我研究了 CDC Cyber 架构,该架构具有 6 位“字节”和 60 位字。 AC 对此的实施将会很有趣。事实上,该架构负责 Pascal 奇怪的打包语义——如果有人还记得的话。
Often developers asking this kind of question are dealing with arranging a packed
struct
to match a defined memory layout (as for a message protocol). The assumption is that the language should directly specify laying out 16-, 24-, 32-bit, etc. fields for the purpose.That is routine and acceptable for assembly languages and other application-specific languages closely tied to a particular CPU architecture, but is sometimes a problem in a general purpose language which might be targeted at who-knows-what kind of architecture.
In fact, the C language was not intended for a particular hardware implementation. It was specified generally so a C compiler implementer could properly adapt to the realities of a particular CPU. A Frankenstein hardware architecture consisting of 9 bit bytes, 54 bit words, and 72 bit memory addresses is easily—and unambiguously—mapped to C features. (
char
is 9 bits;short int
,int
, andlong int
are 54 bits.)This generality is why the C specification says something to the effect of "don't expect much about the sizes of ints beyond sizeof (char) <= sizeof (short int) <= sizeof (int) <= sizeof (long int)." That implies that chars could be the same size as longs!
The current reality is—and the future seems to hold—that software demands architectures provide 8-bit bytes and that memory words addressable as individual bytes. This wasn't always so. Not too long ago, I worked on an the CDC Cyber architecture which features 6 bit "bytes" and 60 bit words. A C implementation on that would be interesting. In fact, that architecture is responsible for the weird packing semantics of Pascal—if anyone remembers that.
C99 N1256标准草案
http ://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
C99 指定了两种类型的整数保证:
相对保证< /strong>
6.2.5 类型:
6.3.1.1 布尔值、字符和整数确定相对转换等级:
绝对最小尺寸
由 https://stackoverflow 提及。 com/a/1738587/895245 ,为了方便起见,这里引用一下。
5.2.4.2.1 整数类型的大小
:浮点
如果定义了
__STDC_IEC_559__
宏,则保证每个浮点数的 IEEE 类型C 类型,尽管long double
有一些可能性:假设浮点数在 C 中使用 IEEE754 浮点数表示是否安全?C99 N1256 standard draft
http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
C99 specifies two types of integer guarantees:
Relative guarantees
6.2.5 Types:
and 6.3.1.1 Boolean, characters, and integers determines the relative conversion ranks:
Absolute minimum sizes
Mentioned by https://stackoverflow.com/a/1738587/895245 , here is the quote for convenience.
5.2.4.2.1 Sizes of integer types
<limits.h>
:Floating point
If the
__STDC_IEC_559__
macro is defined, then IEEE types are guaranteed for each C type, althoughlong double
has a few possibilities: Is it safe to assume floating point is represented using IEEE754 floats in C?引用该标准确实给出了定义为“正确答案”的内容,但它实际上并没有反映程序通常编写的方式。
人们总是假设 char 是 8 位、short 是 16 位、int 是 32 位、long 是 32 或 64 位、long long 是 64 位。
这些假设不是一个好主意,但你不会因为做出这些假设而被解雇。
理论上,
可用于指定固定位宽度类型,但您必须向 Microsoft 寻找一个。 (请参阅此处获取 MS stdint.h。)此处的问题之一从技术上来说,C++ 只需要兼容 C89 即可成为一致的实现;即使对于普通 C,即使在 2009 年,C99 也没有得到完全支持。说
char
没有宽度规范也是不准确的。有,标准只是避免说是否有签名。 C99 实际上是这么说的:CHAR_BIT 8
SCHAR_MIN -127
// -(27 - 1)SCHAR_MAX +127
// 27 - 1UCHAR_MAX 255
// 28 - 1Quoting the standard does give what is defined to be "the correct answer" but it doesn't actually reflect the way programs are generally written.
People make assumptions all the time that char is 8 bits, short is 16, int is 32, long is either 32 or 64, and long long is 64.
Those assumptions are not a great idea but you will not get fired for making them.
In theory,
<stdint.h>
can be used to specify fixed-bit-width types, but you have to scrounge one up for Microsoft. (See here for a MS stdint.h.) One of the problems here is that C++ technically only needs C89 compatibility to be a conforming implementation; even for plain C, C99 is not fully supported even in 2009.It's also not accurate to say there is no width specification for
char
. There is, the standard just avoids saying whether it is signed or not. Here is what C99 actually says:CHAR_BIT 8
SCHAR_MIN -127
// -(27 - 1)SCHAR_MAX +127
// 27 - 1UCHAR_MAX 255
// 28 - 1大多数库都定义了这样的内容:
然后您可以在程序中使用这些 typedef 而不是标准类型。
Most of the libraries define something like this:
you can then use those typedef in your programs instead of the standard types.