【问题标题】:What is the size of float and double in C and C++? [duplicate]C 和 C++ 中 float 和 double 的大小是多少? [复制]
【发布时间】:2014-10-20 20:56:58
【问题描述】:

我想看看是否有任何类似于 uint32_t 的标准类型,它总是会映射到 32 位无符号整数类型,但我找不到。

float 的大小在所有平台上都是 4 字节吗?
double的大小总是8吗?

这两个标准对此事有任何说明吗?

我想确保我的大小在所有平台(x86 和 x64)上始终相同,因此我使用标准 int 类型,但我找不到任何与 floatdouble 相似的 typedef。

【问题讨论】:

  • 您想要 C、C++ 还是两者兼而有之?请说清楚一点。
  • @Deduplicator 主要是c++,但是有什么区别呢?为什么它很重要?
  • 有时,答案是不同的。除此之外,你的问题应该清楚地说明你想问什么。无论如何,在这种情况下,答案是对 C 标准的引用,请看下面。
  • @mans “有什么区别?”它们是不同的语言,由不同的文档指定。 “它为什么如此重要?”因为你实际上是在问两个不同的问题;一种语言的答案可能与另一种语言无关。

标签: c++ c floating-point x86 64-bit


【解决方案1】:

摘自 C99 标准,规范性附件 F(C++ 标准没有明确提及此附件,尽管它包括所有受影响的功能,每个引用都没有更改。此外,为了兼容性,类型必须匹配。):

IEC 60559 浮点运算

F.1 简介

1 本附件规定了对 IEC 60559 浮点标准的 C 语言支持。这 IEC 60559 浮点标准专门用于二进制浮点运算 微处理器系统,第二版 (IEC 60559:1989),先前指定 IEC 559:1989 和作为二进制浮点算术的 IEEE 标准 (ANSI/IEEE 754−1985)。基数无关浮点的 IEEE 标准 算术 (ANSI/IEEE 854−1987) 将二进制标准推广到删除 对基数和字长的依赖。 IEC 60559 一般是指浮点 标准,如 IEC 60559 操作、IEC 60559 格式等。 定义__STDC_IEC_559__ 应符合本附件中的规范。356) 如果指明了 C 语言和 IEC 60559 之间的绑定,则 除非另有说明,否则 IEC 60559 指定的行为以引用方式采用。自从 负无穷和正无穷可以用 IEC 60559 格式表示,所有实数都位于 在可表示的值范围内。

所以,包括<math.h>(或者在C++ 中可能是<cmath>),并测试__STDC_IEC_559__

如果定义了宏,不仅可以更好地指定类型(float 是 32 位,double 是 64 位等),而且内置运算符和标准函数的行为也更加指定。
缺少宏不提供任何保证。

对于 x86 和 x86_64 (amd64),您可以依赖类型 floatdouble 符合 IEC-60559,尽管使用它们的函数和对它们的操作可能不符合。

【讨论】:

  • C++ 中的 double 和 float 类型必须与 C 中的相同类型兼容,因为 C++ 与 C 直接集成。
  • @CashCow:当然。不过,我也想为正在定义的宏提供合理的期望。
【解决方案2】:

没有说明尺寸。

3.9.1.8

共有三种浮点类型:float、double 和 long double。 double 类型至少提供与 float 一样高的精度,并且 long double 类型至少提供与 double 一样多的精度。这 float 类型的值集是值集的子集 双精度型; double 类型的值集是 long double 类型的值集。的价值表示 浮点类型是实现定义的。整体式和浮动式 类型统称为算术类型。的专业 标准模板 std::numeric_limits (18.3) 应指定最大值 以及实现的每种算术类型的最小值。

【讨论】:

    【解决方案3】:

    C++ 标准没有说明任何内容,但在大多数平台中,C++ 使用 IEEE 的单/双精度标准,将单精度定义为 4 个字节,将双精度定义为 8 个字节。

    我不确定这些情况的例外情况。

    【讨论】:

    • 这是否意味着任何使用 IEEE 标准的平台都兼容?平台是硬件相关的开发相关的吗?
    • @mans:不完全兼容。例如,IEEE 并没有对字节顺序表示反对。最高有效位是 IEEE 754 中的符号位,但这并不能告诉您在哪个字节中找到 MSB。
    【解决方案4】:

    由于浮点运算是由 CPU 在低级别实现的,因此 C++ 标准不要求 floatdoublelong double 的大小。它只是说我指定它们的顺序是相同或递增的精度顺序。

    您最好谨慎使用static_assertsizeoftypedef#define 来定义跨平台浮点类型。

    【讨论】:

    • 整数类型没有在比浮点数更高的级别上实现,但自 C99 以来仍然存在精确宽度的固定表示类型。您可能需要进行推理。
    【解决方案5】:

    我想指出,即使您有相同大小的浮动,您也不能确保这些浮动在不同平台上得到相同的解释。你可以阅读很多关于“网络浮动”的论文。浮动不确定性是一个已知问题。

    【讨论】:

    • 如果我们说任何实现IEEE标准的平台都是一样的,是否正确?在我的应用程序中,我需要确保数据从 ARM 系统正确传输到 Intel 基础系统。
    • @mans 那里有不同的 IEEE 标准,不同的编译器可能无法完全实现它们。存在 endianness 问题。所以你不能百分百确定。我建议使用替代方案:1)定点实数; 2)转换为字符串并返回; 3) 使用提供可移植性的现有库。见this
    【解决方案6】:

    您可以尝试使用提供跨平台数据类型兼容性的库。

    “C++继承自C的整数类型有跨平台的风险。int、long和friends在不同的平台上有不同的大小(今天的系统上是32位和64位,以后可能是128位) . 对于某些应用程序,这似乎无关紧要,因为它们永远不会接近 32 位限制(如果使用无符号整数,则更确切地说是 31 位),但是如果您在 64 位系统上序列化对象并在 32 位系统上反序列化您可能会感到不快。
    APR 为在不同平台上可能不同的基本类型提供了一组 typedef。这些 typedef 提供了有保证的大小并避免了模糊的内置类型。但是,对于某些应用程序(主要是数字),有时使用本机机器字长(通常是 int 代表的)来实现最大性能很重要。”

    Gigi SAYFAN - 构建你自己的插件框架 (来自http://philippe.ameline.free.fr/techytechy/071125_PluginFramework.htm

    【讨论】:

    • 使用得当,它们不是危险,而是福音。自然,您需要二进制序列化的固定表示类型。
    • 这是关于 int 类型的,我正在使用它们,但这个问题是关于跨平台类型未涵盖的 float/double 类型。
    【解决方案7】:

    在 X86 的情况下,即使使用 IEEE 单精度和双精度数,内部计算也会受到浮点控制字 (FCW) 的影响。内部计算通常是 64 位或 80 位(long double)。您可以使用内联汇编代码覆盖它,但不能保证某些双精度库函数不会将其设置回来。

    Microsoft 在其 16 位编译器中支持 80 位长双精度,但在其 32 位和 64 位编译器中放弃了对它们的支持,并且长双精度现在与 64 位双精度相同。

    【讨论】: