Long double
{{Short description|Floating-point data type in C family languages}}
{{lowercase title}}
{{floating-point}}
In C and related programming languages, long double
refers to a floating-point data type that is often more precise than double precision though the language standard only requires it to be at least as precise as double
. As with C's other floating-point types, it may not necessarily map to an IEEE format.
<code>long double</code> in C
=History=
The long double
type was present in the original 1989 C standard,ANSI/ISO 9899-1990 American National Standard for Programming Languages - C, section 6.1.2.5. but support was improved by the 1999 revision of the C standard, or C99, which extended the standard library to include functions operating on long double
such as sinl()
and strtold()
.
Long double constants are floating-point constants suffixed with "L" or "l" (lower-case L), e.g., 0.3333333333333333333333333333333333L or 3.1415926535897932384626433832795029L for quadruple precision. Without a suffix, the evaluation depends on FLT_EVAL_METHOD.
=Implementations=
On the x86 architecture, most C compilers implement long double
as the 80-bit extended precision type supported by x86 hardware (generally stored as 12 or 16 bytes to maintain data structure alignment), as specified in the C99 / C11 standards (IEC 60559 floating-point arithmetic (Annex F)). An exception is Microsoft Visual C++ for x86, which makes long double
a synonym for double
.{{Cite web |title=Long Double |url=https://learn.microsoft.com/en-us/previous-versions/9cx8xs15(v=vs.140) |access-date=2022-10-06 |website=learn.microsoft.com | date=20 September 2016 |language=en-us}} The Intel C++ compiler on Microsoft Windows supports extended precision, but requires the /Qlong‑double
switch for long double
to correspond to the hardware's extended precision format.[http://software.intel.com/en-us/articles/size-of-long-integer-type-on-different-architecture-and-os/ Intel Developer Site]
Compilers may also use long double
for the IEEE 754 quadruple-precision binary floating-point format (binary128). This is the case on HP-UX,{{cite book |author=Hewlett Packard |year=1992 |title=HP-UX Portability Guide - HP 9000 Computers |edition=2nd |chapter=Porting C Programs |pages=5-3 and 5-37 |url=http://www.textfiles.com/bitsavers/pdf/hp/9000_hpux/9.x/B2355-90025_HP-UX_Portability_Guide_Aug92.pdf}} Solaris/SPARC,{{Cite web |title=IEEE Arithmetic |url=http://docs.oracle.com/cd/E19957-01/806-3568/ncg_math.html |access-date=2022-10-06 |website=docs.oracle.com}} MIPS with the 64-bit or n32 ABI,{{cite web |date=1999 |title=MIPSpro™ N32 ABI Handbook |url=http://irix7.com/techpubs/007-2816-004.pdf |accessdate=2020-05-26}} 64-bit ARM (AArch64){{cite web |date=2020-10-01 |title=Procedure Call Standard for the Arm® 64-bit Architecture (AArch64) |website=GitHub |url=https://github.com/ARM-software/abi-aa/blob/master/aapcs64/aapcs64.rst |url-status=live |archive-url=https://github.com/ARM-software/abi-aa/releases/download/2020Q3/aapcs64.pdf |archive-date=2020-10-02}} (on operating systems using the standard AAPCS calling conventions, such as Linux), and z/OS with FLOAT(IEEE){{cite web |date=2020-10-09 |title=Floating-point types |website=IBM |url=https://www.ibm.com/support/knowledgecenter/SSLTBW_2.4.0/com.ibm.zos.v2r4.cbclx01/fltvar.htm |accessdate=2020-10-09}}{{cite web |last=Schwarz |first=Eric |date=June 22, 2015 |title=The IBM z13 SIMD Accelerators for Integer, String, and Floating-Point |url=http://arith22.gforge.inria.fr/slides/s1-schwarz.pdf |accessdate=July 13, 2015}}{{cite journal |last1=Schwarz |first1=E. M. |last2=Krygowski |first2=C. A. |date=September 1999 |title=The S/390 G5 floating-point unit |journal=IBM Journal of Research and Development |doi=10.1147/rd.435.0707 |volume=43 |issue=5/6 |pages=707–721 |citeseerx=10.1.1.117.6711 }}. Most implementations are in software, but some processors have hardware support.
On some PowerPC systems,{{Cite web|title=The saga of the Power ISA 128-bit long double|url=https://www.talospace.com/2018/12/the-saga-of-power-isa-128-bit-long.html|date=2018-12-22|access-date=2021-12-26}} long double
is implemented as a double-double arithmetic, where a long double
value is regarded as the exact sum of two double-precision values, giving at least a 106-bit precision; with such a format, the long double
type does not conform to the IEEE floating-point standard. Otherwise, long double
is simply a synonym for double
(double precision), e.g. on 32-bit ARM,{{cite web |year=2013 |title=ARM® Compiler toolchain Compiler Reference, Version 5.03 |at=Section 6.3 Basic data types |url=http://infocenter.arm.com/help/topic/com.arm.doc.dui0491i/DUI0491I_arm_compiler_reference.pdf |accessdate=2019-11-08}} 64-bit ARM (AArch64) (on Windows{{cite web |title=llvm/llvm-project |website=GitHub |url=https://github.com/llvm/llvm-project/blob/3d54976a704327aea8de85f7b2c36172e42100d9/clang/lib/Basic/Targets/AArch64.cpp#L741-L746 |access-date=2020-09-03}} and macOS{{cite web |title=llvm/llvm-project |website=GitHub |url=https://github.com/llvm/llvm-project/blob/3d54976a704327aea8de85f7b2c36172e42100d9/clang/lib/Basic/Targets/AArch64.cpp#L838-L839 |access-date=2020-09-03}}) and on 32-bit MIPS{{cite web |date=1996 |title=System V Application Binary Interface: MIPS(r) Processor Supplement |edition=3rd |url=http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf |accessdate=2020-05-26}} (old ABI, a.k.a. o32).
With the GNU C Compiler, long double
is 80-bit extended precision on x86 processors regardless of the physical storage used for the type (which can be either 96 or 128 bits),{{Cite web |title=x86 Options (Using the GNU Compiler Collection (GCC)) |url=https://gcc.gnu.org/onlinedocs/gcc/x86-Options.html |access-date=2022-10-06 |website=gcc.gnu.org}} On some other architectures, long double
can be double-double (e.g. on PowerPC{{Cite web |title=RS/6000 and PowerPC Options (Using the GNU Compiler Collection (GCC)) |url=https://gcc.gnu.org/onlinedocs/gcc/RS_002f6000-and-PowerPC-Options.html |access-date=2022-10-06 |website=gcc.gnu.org}}[https://developer.apple.com/legacy/mac/library/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf Inside Macintosh - PowerPC Numerics] {{webarchive|url=https://web.archive.org/web/20121009191824/http://developer.apple.com/legacy/mac/library/documentation/Performance/Conceptual/Mac_OSX_Numerics/Mac_OSX_Numerics.pdf |date=2012-10-09 }}[https://opensource.apple.com/source/gcc/gcc-5646/gcc/config/rs6000/darwin-ldouble.c 128-bit long double support routines for Darwin]) or 128-bit quadruple precision (e.g. on SPARC{{Cite web |title=SPARC Options (Using the GNU Compiler Collection (GCC)) |url=https://gcc.gnu.org/onlinedocs/gcc/SPARC-Options.html |access-date=2022-10-06 |website=gcc.gnu.org}}). As of gcc 4.3, a quadruple precision is also supported on x86, but as the nonstandard type __float128
rather than long double
.{{Cite web |title=GCC 4.3 Release Series — Changes, New Features, and Fixes - GNU Project |url=https://gcc.gnu.org/gcc-4.3/changes.html |access-date=2022-10-06 |website=gcc.gnu.org}}
Although the x86 architecture, and specifically the x87 floating-point instructions on x86, supports 80-bit extended-precision operations, it is possible to configure the processor to automatically round operations to double (or even single) precision. Conversely, in extended-precision mode, extended precision may be used for intermediate compiler-generated calculations even when the final results are stored at a lower precision (i.e. FLT_EVAL_METHOD == 2). With gcc on Linux, 80-bit extended precision is the default; on several BSD operating systems (FreeBSD and OpenBSD), double-precision mode is the default, and long double
operations are effectively reduced to double precision.Brian J. Gough and Richard M. Stallman, An Introduction to GCC, section 8.6 [http://www.network-theory.co.uk/docs/gccintro/gccintro_70.html Floating-point issues] (Network Theory Ltd., 2004). (NetBSD 7.0 and later, however, defaults to 80-bit extended precision {{cite web |title=Significant changes from NetBSD 6.0 to 7.0 |url=https://www.netbsd.org/changes/changes-7.0.html}}). However, it is possible to override this within an individual program via the FLDCW "floating-point load control-word" instruction. On x86_64, the BSDs default to 80-bit extended precision. Microsoft Windows with Visual C++ also sets the processor in double-precision mode by default, but this can again be overridden within an individual program (e.g. by the _controlfp_s
function in Visual C++{{Cite web |title=Visual Studio 2005 Retired documentation |url=https://www.microsoft.com/en-us/download/details.aspx?id=55984 |access-date=2022-10-06 |website=Microsoft Download Center |language=en-us}}). The Intel C++ Compiler for x86, on the other hand, enables extended-precision mode by default.Intel C++ Compiler Documentation, [http://www.nacad.ufrj.br/online/intel/Documentation/en_US/compiler_c/main_cls/index.htm Using the -fp-model (/fp) Option]. On IA-32 OS X, long double
is 80-bit extended precision.{{Cite web|url=https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/LowLevelABI/130-IA-32_Function_Calling_Conventions/IA32.html|title = IA-32 Function Calling Conventions}}
Other specifications
In CORBA (from specification of 3.0, which uses "ANSI/IEEE Standard 754-1985" as its reference), "the long double data type represents an IEEE double-extended floating-point number, which has an exponent of at least 15 bits in length and a signed fraction of at least 64 bits", with GIOP/IIOP CDR, whose floating-point types "exactly follow the IEEE standard formats for floating point numbers", marshalling this as what seems to be IEEE 754-2008 binary128 a.k.a. quadruple precision without using that name.
See also
References
{{data types}}
{{DEFAULTSORT:Long Double}}