В C и родственных языках программированияlong double
относится к типу данных с плавающей точкой , который часто точнее, чем двойная точность, хотя стандарт языка требует, чтобы он был по крайней мере такой же точной, как . Как и другие типы данных с плавающей точкой в C, он не обязательно может соответствовать формату IEEE .double
Тип long double
присутствовал в оригинальном стандарте C 1989 года [1], но его поддержка была улучшена в редакции стандарта C 1999 года, или C99 , которая расширила стандартную библиотеку , включив в нее функции, работающие с long double
такими объектами, как sinl()
и strtold()
.
Длинные двойные константы — это константы с плавающей точкой с суффиксом "L" или "l" (строчная L), например, 0.33333333333333333333333333333333333L или 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
. [2] Компилятор Intel C++ на Microsoft Windows поддерживает расширенную точность, но требует /Qlong‑double
переключения для long double
соответствия формату расширенной точности оборудования. [3]
Компиляторы также могут использовать long double
для IEEE 754 двоичный формат с плавающей точкой четверной точности (binary128). Это касается HP-UX , [4] Solaris / SPARC , [5] MIPS с 64-битным или n32 ABI , [6] 64-битного ARM (AArch64) [7] (в операционных системах, использующих стандартные соглашения о вызовах AAPCS, таких как Linux), и z/OS с FLOAT(IEEE) [8] [9] [10] . Большинство реализаций реализованы в программном обеспечении, но некоторые процессоры имеют аппаратную поддержку .
В некоторых системах PowerPC [11] long double
реализовано как арифметика double-double , где long double
значение рассматривается как точная сумма двух значений двойной точности, что дает по крайней мере 106-битную точность; с таким форматом тип long double
не соответствует стандарту IEEE с плавающей точкой . В противном случае, long double
является просто синонимом double
(двойной точности), например, на 32-битном ARM , [12] 64-битном ARM (AArch64) (на Windows [13] и macOS [14] ) и на 32-битном MIPS [15] (старый ABI, он же o32).
С компилятором GNU C , long double
это 80-битная расширенная точность на процессорах x86 независимо от физического хранилища, используемого для типа (которое может быть либо 96, либо 128 бит), [16] На некоторых других архитектурах, long double
может быть двойной двойной точностью (например, на PowerPC [17] [18] [19] ) или 128-битной четверной точностью (например, на SPARC [20] ). Начиная с gcc 4.3, четверная точность также поддерживается на x86, но как нестандартный тип, __float128
а не long double
. [21]
Хотя архитектура x86, и в частности инструкции с плавающей точкой x87 на x86, поддерживают 80-битные операции с расширенной точностью, можно настроить процессор на автоматическое округление операций до двойной (или даже одинарной) точности. И наоборот, в режиме расширенной точности расширенная точность может использоваться для промежуточных вычислений, генерируемых компилятором, даже если конечные результаты хранятся с более низкой точностью (т. е. FLT_EVAL_METHOD == 2 ). С gcc на Linux 80-битная расширенная точность является значением по умолчанию; в нескольких операционных системах BSD ( FreeBSD и OpenBSD ) режим двойной точности является значением по умолчанию, и long double
операции фактически сводятся к двойной точности. [22] ( Однако NetBSD 7.0 и более поздние версии по умолчанию используют 80-битную расширенную точность [23] ). Однако это можно переопределить в отдельной программе с помощью инструкции FLDCW "управляющее слово загрузки с плавающей точкой". [22] На x86_64 BSD по умолчанию использует 80-битную расширенную точность. Microsoft Windows с Visual C++ также устанавливает процессор в режим двойной точности по умолчанию, но это снова можно переопределить в отдельной программе (например, функцией _controlfp_s
в Visual C++ [24] ). С другой стороны, компилятор Intel C++ для x86 включает режим расширенной точности по умолчанию. [25] На IA-32 OS X long double
используется 80-битная расширенная точность. [26]
В CORBA (из спецификации 3.0, которая использует « Стандарт ANSI/IEEE 754-1985 » в качестве ссылки) «тип данных long double представляет собой расширенное до двойной точности число IEEE с плавающей точкой, имеющее экспоненту длиной не менее 15 бит и знаковую дробь длиной не менее 64 бит», с GIOP/IIOP CDR, типы данных с плавающей точкой которого «точно следуют стандартным форматам IEEE для чисел с плавающей точкой», маршалируя это как то, что, по-видимому, является IEEE 754-2008 binary128, или четверной точностью, без использования этого названия.