C ++编译器中存在哪些不常见的浮点大小

时间:2016-07-21 16:00:11

标签: c++ floating-point

关于float,double和long double的具体要求,C ++ 14草案标准似乎相当安静,尽管这些大小似乎很常见:

  • float:IEEE 32位浮点表示(大约7位精度,指数范围1e-38..1e + 38)

  • double:IEEE 64位浮点表示(大约16位精度,指数范围为1e-308..1e + 308)

  • long double:80位浮点表示(大约19位精度,指数范围为1e-4951..1e + 4932)

目前哪些C ++编译器和系统使用浮点大小?

我对使用标准类型而不是库的更长,更短和非二进制表示感兴趣,因为我的主要兴趣是C ++程序的可移植性。

3 个答案:

答案 0 :(得分:2)

如果您只询问位大小,那么奇数大小类型仅存在于一些不使用8位(或2的幂)的旧平台中,例如{ {3}},具有36位浮点数和72位double。直到现在,那只野兽仍在活跃地发展。 Unisys ClearPath Dorado Servers是在2018年。大型机和服务器的寿命很长,因此您仍然可以通过现代编译器支持在现代使用last version

如果您关心 formats ,那么有很多标准兼容的32位,64位和128位浮点格式,它们不是IEEE-754的,就像IBM中的PDP-10 and other architectures z,hex and decimal floating point typesCray formats。实际上,IBM z是使用十进制浮点硬件的非常罕见的现代平台之一,尽管如果使用GCC和某些其他编译器,则可以使用其VAX formats。 IBM还使用了特殊的双精度双精度格式,到目前为止,long double仍是PowerPC上默认使用的格式。

一些用于微控制器的现代C / C ++编译器中还存在其他一些非标准的24位浮点数

以下是大多数built-in software support for decimal float的摘要。另请参见available floating-point formats。有关更多信息,请继续下一节


由于性能原因,C ++中的

类型通常映射到硬件类型。因此,如果有FPU,浮点类型将是CPU上可用的任何类型。在现代计算机中,IEEE-754是硬件中的主要格式,并且由于C ++标准floatdouble的要求,必须至少映射到IEEE-754 Do any real-world CPUs not use IEEE 754?和{{3 }}精度

除了x86和其他一些带有single的罕见平台之外,对精度更高的类型的硬件支持并不普遍,因此 long double通常映射到在这些平台上与double 具有相同的类型。然而,最近long double在许多编译器(例如GCC或Clang)中正缓慢迁移到double。由于该程序是通过内置的软件库实现的,因此性能会大大降低。根据您是希望执行速度更快还是精度更高,仍然可以自由选择long double映射到的任何类型。例如,在x86上,GCC具有80-bit extended precision来设置long double的填充和格式。该选项在IEEE-754 quadruple precision

等许多其他体系结构中也可用

默认情况下,PowerPC OTOH使用通过-mlong-double-64/80/128 and -m96/128bit-long-double options实现的完全不同的128位长双精度格式,并且具有与IEEE-754双精度相同的范围。它的精度略低于四倍精度,但由于可以利用硬件双重运算,因此速度要快得多。如上所述,您可以使用S/390 and zSeries在2种格式之间进行选择。在某些double-double arithmetic中也使用了这种技巧,以获得接近两倍的精度

IBM z大型机传统上使用-mabi=ibmlongdouble/ieeelongdouble options,但如今仍在使用。但除此之外,他们还platforms where only 32-bit float is supported

浮点数的格式可以是基数为16的S /390®十六进制格式,基数为2的IEEE-754二进制格式或基数为10的IEEE-754十进制格式。格式基于十六进制和二进制的三种操作数长度:短(32位),长(64位)和扩展(128位)。格式还基于三种十进制操作数长度:_Decimal32(32位),_ Decimal64(64位)和_Decimal128(128位)。

IBM hex float formats

其他体系结构可能具有其他浮点格式,例如VAX或Cray。但是,由于这些大型机仍在使用,它们的较新的硬件版本也包括对IEEE-754的支持,就像IBM对其大型机所做的那样。

在没有FPU的现代平台上,浮点类型通常为IEEE-754单精度和双精度,以实现更好的互操作性和库支持。但是,在8位微控制器上,即使单精度也太昂贵了,因此某些编译器支持非标准模式,其中float是24位类型。例如, XC8编译器使用support IEEE-754 binary and decimal floating-point types(是32位格式的截断形式)Floating-point numbers

由于需要较窄浮点类型的图形和AI应用程序的兴起,许多平台还引入了诸如IEEE-754 binary16和Google的bfloat16之类的16位浮点格式,并且编译器也对其提供了有限的支持,例如24-bit floating-point format

答案 1 :(得分:1)

首先,我是stackoverflow的新手,所以请耐心等待。

然而,要回答你的问题。查看 floath.h 标头,它们为:

指定浮点参数
  1. 英特尔编译器

    //Float:
    #define FLT_MAX                 3.40282347e+38F
    
    //Double:
    #define DBL_MAX                 1.7976931348623157e+308
    
    //Long Double:
    #if (__IMFLONGDOUBLE == 64) || defined(__LONGDOUBLE_AS_DOUBLE)
    #define LDBL_MAX                    1.7976931348623157e+308L
    #else
    #define LDBL_MAX                1.1897314953572317650213E+4932L
    
  2. GCC(MinGW实际上是gcc 4或5)

    //Float:
    #define FLT_MAX         3.40282347e+38F
    
    //Double:
    #define DBL_MAX     1.7976931348623157e+308
    
    //Long Double: (same as double for gcc):
    #define LDBL_MAX        1.7976931348623157e+308L
    
  3. 微软

    //Float:
    #define FLT_MAX         3.40282347e+38F
    
    //Double:
    #define DBL_MAX     1.7976931348623157e+308
    
    //Long Double: (same as double for Microsoft):
    #define LDBL_MAX            DBL_MAX
    
  4. 因此,正如您所看到的,只有英特尔编译器在“标准”Windows机器上为长双精度提供80位表示。

    此数据从windows机器的相应float.h头文件中复制。

答案 2 :(得分:0)

“浮点数”和“双精度”在IEEE单精度和双精度表示法上事实上已标准化。我将假设这些大小与假设CHAR_BIT == 8放在同一类别中。某些较早的手臂系统确实具有“混合字节序”双曲的怪异之处,但是除非您使用复古的东西,否则如今不太可能遇到这种情况。

另一方面,long double的可变性要大得多。有时是IEEE双精度,有时是80位x87扩展,有时是IEEE四精度,有时是由两个IEEE双精度数字加在一起构成的“双精度双精度”格式。

因此,在可移植代码中,您不能依靠“ long double”比“ double”更好。