long double
Floating-point formats |
---|
IEEE 754 |
|
Other |
Alternatives |
Tapered 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.
long double
in C
[edit]History
[edit]The long double
type was present in the original 1989 C standard,[1] 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
[edit]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
.[2] 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.[3]
Compilers may also use long double
for the IEEE 754 quadruple-precision binary floating-point format (binary128). This is the case on HP-UX,[4] Solaris/SPARC,[5] MIPS with the 64-bit or n32 ABI,[6] 64-bit ARM (AArch64)[7] (on operating systems using the standard AAPCS calling conventions, such as Linux), and z/OS with FLOAT(IEEE)[8][9][10]. Most implementations are in software, but some processors have hardware support.
On some PowerPC systems,[11] 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,[12] 64-bit ARM (AArch64) (on Windows[13] and macOS[14]) and on 32-bit MIPS[15] (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),[16] On some other architectures, long double
can be double-double (e.g. on PowerPC[17][18][19]) or 128-bit quadruple precision (e.g. on SPARC[20]). As of gcc 4.3, a quadruple precision is also supported on x86, but as the nonstandard type __float128
rather than long double
.[21]
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.[22] (NetBSD 7.0 and later, however, defaults to 80-bit extended precision [23]). However, it is possible to override this within an individual program via the FLDCW "floating-point load control-word" instruction.[22] 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++[24]). The Intel C++ Compiler for x86, on the other hand, enables extended-precision mode by default.[25] On IA-32 OS X, long double
is 80-bit extended precision.[26]
Other specifications
[edit]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
[edit]References
[edit]- ^ ANSI/ISO 9899-1990 American National Standard for Programming Languages - C, section 6.1.2.5.
- ^ "Long Double". learn.microsoft.com. 20 September 2016. Retrieved 2022-10-06.
- ^ Intel Developer Site
- ^ Hewlett Packard (1992). "Porting C Programs". HP-UX Portability Guide - HP 9000 Computers (PDF) (2nd ed.). pp. 5-3 and 5-37.
- ^ "IEEE Arithmetic". docs.oracle.com. Retrieved 2022-10-06.
- ^ "MIPSpro™ N32 ABI Handbook" (PDF). 1999. Retrieved 2020-05-26.
- ^ "Procedure Call Standard for the Arm® 64-bit Architecture (AArch64)". GitHub. 2020-10-01. Archived (PDF) from the original on 2020-10-02.
- ^ "Floating-point types". IBM. 2020-10-09. Retrieved 2020-10-09.
- ^ Schwarz, Eric (June 22, 2015). "The IBM z13 SIMD Accelerators for Integer, String, and Floating-Point" (PDF). Retrieved July 13, 2015.
- ^ Schwarz, E. M.; Krygowski, C. A. (September 1999). "The S/390 G5 floating-point unit". IBM Journal of Research and Development. 43 (5/6): 707–721. CiteSeerX 10.1.1.117.6711. doi:10.1147/rd.435.0707.
- ^ "The saga of the Power ISA 128-bit long double". 2018-12-22. Retrieved 2021-12-26.
- ^ "ARM® Compiler toolchain Compiler Reference, Version 5.03" (PDF). 2013. Section 6.3 Basic data types. Retrieved 2019-11-08.
- ^ "llvm/llvm-project". GitHub. Retrieved 2020-09-03.
- ^ "llvm/llvm-project". GitHub. Retrieved 2020-09-03.
- ^ "System V Application Binary Interface: MIPS(r) Processor Supplement" (PDF) (3rd ed.). 1996. Retrieved 2020-05-26.
- ^ "x86 Options (Using the GNU Compiler Collection (GCC))". gcc.gnu.org. Retrieved 2022-10-06.
- ^ "RS/6000 and PowerPC Options (Using the GNU Compiler Collection (GCC))". gcc.gnu.org. Retrieved 2022-10-06.
- ^ Inside Macintosh - PowerPC Numerics Archived 2012-10-09 at the Wayback Machine
- ^ 128-bit long double support routines for Darwin
- ^ "SPARC Options (Using the GNU Compiler Collection (GCC))". gcc.gnu.org. Retrieved 2022-10-06.
- ^ "GCC 4.3 Release Series — Changes, New Features, and Fixes - GNU Project". gcc.gnu.org. Retrieved 2022-10-06.
- ^ a b Brian J. Gough and Richard M. Stallman, An Introduction to GCC, section 8.6 Floating-point issues (Network Theory Ltd., 2004).
- ^ "Significant changes from NetBSD 6.0 to 7.0".
- ^ "Visual Studio 2005 Retired documentation". Microsoft Download Center. Retrieved 2022-10-06.
- ^ Intel C++ Compiler Documentation, Using the -fp-model (/fp) Option.
- ^ "IA-32 Function Calling Conventions".