长双精度C++是IEEE二进制128的实现吗?

Is long double in C++ an implementation of IEEE's binary128?

本文关键字:实现 二进制 双精度 C++ IEEE      更新时间:2023-10-16

来自 https://en.wikipedia.org/wiki/Long_double:

在C++中,long double是指通常比双精度更精确的浮点数据类型。但是,与C++的其他浮点类型一样,它可能不一定映射到 IEEE 格式。

使用 GNU C 编译器,long doublex86 处理器上的扩展精度为 80 位,而与用于该类型的物理存储(可以是 96 位或 128 位(无关。在其他一些体系结构上,long double可以是double-double(例如在PowerPC上(或128位四倍精度(例如在SPARC上(。从 gcc 4.3 开始,x86 也支持四倍精度,但非标准类型__float128而不是long double

在 Linux 上使用 gcc,80 位扩展精度是默认值;在几个 BSD 操作系统(FreeBSD 和 OpenBSD(上,双精度模式是默认的,长双精度操作有效地降低到双精度。

另一方面,面向 x86 的英特尔C++编译器默认启用扩展精度模式。在 OS X 上,长双精度是 80 位扩展精度。

看起来确实long double可能不是IEEE二进制128的实现,但为什么不这样做呢?为什么在某些情况下默认为 80 位表示形式?

为什么在某些情况下默认为 80 位表示形式?

因为某些平台可能能够在硬件中提供高效的 80 位浮点运算,但不能提供 128 位浮点运算。这与标准未指定sizeof(int)的原因相同 - 在某些平台上,32 位整数可能效率不高/不可用。

long doublein C++是 IEEE 二进制 128 的实现吗?

不,C++甚至不需要对浮点类型使用 IEEE-754。看

  • C++标准是否对浮点数的表示有任何规定?
  • 假设浮点数在 C 中使用IEEE754浮点数表示是否安全?

仅从 C++11 开始,您才能检查平台是否使用 IEEE-754 和std::numeric_limits<T>::is_iec559


为什么在某些情况下默认为 80 位表示形式?

因为 x87 支持 80 位 IEEE-754 扩展精度格式。摩托罗拉6888x和Intel i960等一些后来的平台也支持这种类型,因此编译器将其用于long double而不是诉诸慢得多的软件仿真是有意义的。

这也是PowerPC默认使用双双long double的原因,因为您可以使用硬件double单元,从而使操作更快。旧的NVIDIA CUDA核心没有硬件支持double,所以很多人使用浮点浮动以获得更大的精度。请参阅在 GPU 上使用 2 个 FP32 模拟 FP64

在 Itanium 的情况下,浮点寄存器是 82 位宽的,那么long double很可能具有相同的宽度,并带有一些填充以正确对齐到 128 位

大多数其他架构没有大于 64 位的浮点类型的硬件,因此他们选择了 IEEE-754四精度格式,以便于实现和更好的向前兼容性,因为如果有一天对 128 位浮点的支持出现在真正的硬件上,它很可能是 IEEE-754 四精度。目前,Sparc是唯一支持四精度硬件的架构

也就是说,大多数编译器都可以选择更改long double的基础格式。例如,在GCC中,x86具有-mlong-double-64/80/128-m96/128bit-long-double,PowerPC具有-mabi=ibmlongdouble/ieeelongdouble