Введение

Тип данных с плавающей точкой в языках семейства C

В языках C и связанных с ними языках программирования, `long double` обозначает тип данных с плавающей точкой, который часто обладает большей точностью, чем тип `double`, хотя стандарт языка лишь требует, чтобы он был как минимум столь же точен, как `double`. Как и другие типы данных с плавающей точкой в C, он не обязательно соответствует формату IEEE.

История

Тип long double присутствовал в оригинальном стандарте C 1989 года, но поддержка была улучшена в пересмотре стандарта C 1999 года, или C99, который расширил стандартную библиотеку, включив в нее функции, работающие с long double, такие как sinl и strtold. Константы long double – это константы с плавающей точкой, к которым добавлен суффикс "L" или "l" (строчная L), например, 0.3333333333333333333333333333333333L или 3.1415926535897932384626433832795029L для четверной точности. Без суффикса вычисление зависит от FLT_EVAL_METHOD.

Реализация

На архитектуре x86 большинство компиляторов C реализуют `long double` как 80-битный тип расширенной точности, поддерживаемый аппаратным обеспечением x86 (обычно хранится в виде 12 или 16 байт для обеспечения выравнивания структуры данных), как это определено в стандартах C99 / C11 (арифметика чисел с плавающей запятой IEC 60559, Приложение F). Исключением является Microsoft Visual C++ для x86, который делает `long double` синонимом `double`. Компилятор Intel C++ в Microsoft Windows поддерживает расширенную точность, но требует переключателя `/Qlong-double`, чтобы `long double` соответствовал расширенному формату точности, обеспечиваемому аппаратным обеспечением. Компиляторы также могут использовать `long double` для представления формата чисел с плавающей запятой двойной точности IEEE 754 (binary128). Это справедливо для HP-UX, Solaris/SPARC, MIPS с 64-битным или n32 ABI, 64-битных ARM (AArch64) (на операционных системах, использующих стандартные соглашения о вызовах AAPCS, такие как Linux), и z/OS с FLOAT(IEEE). Большинство реализаций выполняются программно, но некоторые процессоры имеют аппаратную поддержку. На некоторых системах PowerPC `long double` реализован как арифметика двойной двойной точности, где значение `long double` рассматривается как точная сумма двух значений двойной точности, обеспечивая точность не менее 106 бит; в этом формате тип `long double` не соответствует стандарту IEEE 754. В противном случае `long double` является просто синонимом `double` (двойной точности), например, на 32-битных ARM, 64-битных ARM (AArch64) (на Windows и macOS) и на 32-битных MIPS (старый ABI, также известный как o32). При использовании компилятора GNU C, `long double` имеет расширенную точность 80 бит на процессорах x86, независимо от физического хранилища, используемого для этого типа (которое может быть 96 или 128 бит). На некоторых других архитектурах `long double` может быть представлен как двойная двойная точность (например, на PowerPC) или как 128-битная четверная точность (например, на SPARC). Начиная с версии gcc 4.3, четверная точность также поддерживается на x86, но как нестандартный тип `float128`, а не `long double`. Хотя архитектура x86, и в частности инструкции x87 с плавающей запятой на x86, поддерживают 80-битные операции расширенной точности, можно настроить процессор для автоматического округления операций до двойной (или даже одинарной) точности. И наоборот, в режиме расширенной точности расширенная точность может использоваться для промежуточных вычислений, генерируемых компилятором, даже если конечные результаты хранятся с меньшей точностью (то есть, FLT EVAL METHOD == 2). При использовании gcc на Linux расширенная точность 80 бит является значением по умолчанию; на нескольких операционных системах BSD (FreeBSD и OpenBSD) режим двойной точности является значением по умолчанию, и операции с `long double` фактически приводятся к двойной точности. (Однако, начиная с NetBSD 7.0, по умолчанию используется расширенная точность 80 бит). Тем не менее, это можно переопределить в отдельной программе с помощью инструкции FLDCW ("floating point load control word"). С другой стороны, компилятор Intel C++ для x86 включает режим расширенной точности по умолчанию. На IA 32 OS X `long double` имеет расширенную точность 80 бит.

Другие спецификации

В CORBA (согласно спецификации 3.0, использующей "ANSI/IEEE Standard 754 1985" в качестве эталона), "тип данных `long double` представляет собой число двойной расширенной точности формата IEEE, имеющее экспоненту длиной не менее 15 бит и знакомую мантиссу длиной не менее 64 бит". При использовании GIOP/IIOP CDR, типы данных с плавающей точкой "строго соответствуют стандартным форматам IEEE для чисел с плавающей точкой", и при этом сериализуются как формат IEEE 754 2008 binary128, также известный как четырехкратная точность, но без использования этого наименования.