微软的edX C ++课程:双重vs长双 - 为什么缺乏通用标准?

时间:2018-05-03 06:57:40

标签: c++ types edx

我在软件开发A.S.当地社区学院的学位课程。我想要超越我的大学课程(我觉得太简单了)。所以,我正在各处学习不同的语言和技术(在线)。

我决定在edX上学习微软的C ++课程。 据他们说,双倍和长双倍的大小和范围相同(见下面的截图)。这与这些规格相矛盾:

https://en.wikipedia.org/wiki/C_data_types

起初,我认为微软打错了,但后来我发现了this post

  

在x86架构上,大多数编译器都实现了long double   该硬件支持的80位扩展精度类型(有时   存储为12或16个字节以维护数据结构。

     

     

编译器也可以使用long double来获得128位四倍精度   格式,目前在软件中实现。

     

换句话说,是的,长双倍可能能够存储更大的范围   价值比双倍。但这完全取决于编译器。

所以,我认为,在大多数情况下(即,在大多数编译器实现中),Microsoft是错误的,但在某些情况下它们可能是正确的。

但后来我回顾了C ++ 11标准。它在这里说的是:

  

有三种浮点类型:float,double和long double。   double类型提供至少与float一样多的精度   类型long double提供至少与double一样多的精度。该   float类型的值集是该组值的子集   双重类型; double类型的值集是。的子集   long double类型的值集。

模糊,对吧?

所以,这是问题:C ++已经存在了很长时间。为什么这种东西还没有坚实的共同标准?它是故意为了灵活性 - 每个人都自己决定这些数据类型是什么。或者他们只是不能让每个人都参与其中?

谢谢。

截图: Microsoft C++ on edX

P.S。我仍然认为微软应该以不同的方式编写它:“Long Double与double或更多(最多......字节)相同的大小”。

1 个答案:

答案 0 :(得分:1)

  

根据它们,double和long double的大小和范围相同(请参见下面的屏幕截图)。这与这些规格相矛盾:

这里没有矛盾。如果您已仔细阅读 standard 链接的文章,您会看到the C standard specifies the minimum possible ranges of types而不是它们的固定大小。另请注意,上面的Wiki链接适用于C,而不适用于C ++。它们是 非常 不同的语言。幸运的是,他们都同意类型的大小

这允许灵活性,因为C和C ++始终为可移植性而设计。其主要理念是“您不用为不使用的东西付费” ,因此编译器实现必须为每种特定架构选择最有效的解决方案。它们不能强制int始终为32位长。例如,在18位体系结构上,int将具有18位而不是笨拙的32位大小,并且如果int被定义为a,则16位CPU不必浪费支持32位int的周期。 16位类型

这就是为什么C和C ++允许带符号整数类型使用1的补码和符号幅度而不是2的补码。浮点类型也没有强制具有固定大小或为二进制,因此实现可以使用十进制浮点类型。实际上,甚至不需要IEEE-754,因为有些计算机使用其他浮点格式。参见Do any real-world CPUs not use IEEE 754?

因此,阅读ISO/IEC 9899:201x C++ standard,第5.2.4.2.1节(整数类型<limits.h>的大小),我们知道:

  

以下给出的值应由适合#if预处理指令中使用的常量表达式代替。 […] 其实现定义的值的大小(绝对值)应等于或大于所示的值,并带有相同的符号

INT_MAX对应的值为32767,这意味着INT_MAX >= 32767在任何符合要求的实现中。第5.2.4.2.2节(浮点类型<float.h>的特征)中的浮点类型也是如此

您在标准中阅读的内容

  • precisionOf(float)⩽precisionOf(double)⩽precisionOf(long double)和
  • setOfValues(float)⊂setOfValues(double)⊂setOfValues(long double)

非常清楚,一点也不模糊。实际上,您只能保证拥有

  • CHAR_BIT⩾8
  • sizeof(char)⩽sizeof(short)⩽sizeof(int)⩽sizeof(long)⩽sizeof(long long)
  • sizeof(float)⩽sizeof(double)⩽sizeof(long double)
  • FLT_DECIMAL_DIG⩾6
  • LDBL_DECIMAL_DIG⩾DBL_DECIMAL_DIG⩾10

因此,允许doublelong double具有相同的大小和精度。实际上,在非x86平台上它们通常具有相同的类型是因为它们没有像x86这样的extended precision type。最近,许多实现已将long double的软件转换为基于软件的IEEE-754 quadruple-precision,但是当然会慢很多

由于long double的格式很多,因此还有许多选择long double大小的选项,例如当人们不需要额外的精度或不希望软件实现。例如

  • GCC for x86-mlong-double-64/80/128取决于您要使用64位(即与double相同),80位(扩展精度)还是128位(四精度) long double。同样,如果您想以25%的内存使用量来交换速度,则有-m96/128bit-long-double选项
  • GCC for PowerPC具有-mabi=ibmlongdouble/ieeelongdouble的{​​{3}}实现或标准的四精度格式,其范围更广,精度稍好,但速度慢得多。
  

C ++已经存在很长时间了。为什么这类材料仍然没有统一的通用标准?为了灵活起见,是否有意为之?每个人自己决定这些数据类型将是什么

正如我在上面所说的,正是出于灵活性的考虑这是故意的。当您不需要高于double的精度时,就不必为性能和内存使用的损失付费。标准委员会关心那里的每一种可能的体系结构,包括一些可能死掉的体系结构 1

实际上,当FLT_EVAL_METHOD = 2时,允许更高的long double有时会导致意外的结果,因为floatdouble运算也以较高的精度完成,因此在不同点的相同表达可能会有不同的结果。此外,无法向量化奇数扩展精度long double数学 2 会导致更差的性能。因此,即使在x86 MS的cl.exe编译器中,也完全禁止使用80位长的double

另请参见


1 参见


2 参见