long double

From PEGWiki
Jump to: navigation, search

long double is a primitive floating-point data type in C (and subsequently C++) that is required by the standard to be at least as long as a double. That is, the values it can represent must be a superset of the values that a double can represent.

On many architectures, long double is identical to double, since double is usually a binary64 and many architectures do not support a longer floating-point data type. On Intel x86 machines, however, long double is often a 80-bit extended precision format that originated with the Intel 8087 numeric coprocessor. This format is almost exactly analogous to the IEEE 754 formats, except that its significand does not carry an implicit leading 1. It consists of a sign bit, a 15-bit biased exponent field, and a 64-bit significand field. Because the x86 processors are little-endian, when this kind of number is stored in memory, the lowest-address 8 bytes are used for the significand, the next byte is used for the least significant 8 bits of the exponent, and the last byte contains the sign bit as the most significant bit, followed by the most significant 7 bits of the exponent.

In Pascal, the corresponding data types are Extended (Free/Borland/GNU Pascal) and also LongReal (GNU Pascal), which also hold 80 bits of information.

Properties

The range of a long double can be checked in C using <float.h> and C++ using std::numeric_limits. This 80-bit format typically has a range of roughly 1.9E-4932 ... 1.1E+4932 and holds 19-20 significant digits.

Even though the long double may be stored using 96 or even 128 bits (you can check the number of bits using 8*sizeof(long double)), it still only has 80 bits of precision. The extra padding bits are to help modern architectures align to 8 or 16 bit boundaries. In GCC, the compiler switches -m96bit-long-double and -m128bit-long-double may be used to control the storage size of a long double, without of course, changing its precision in any way.

Usage

To scanf or printf a long double, one should use the format specifier %Lf (%llf also works sometimes, although it is nonstandard).

A well-known bug on Windows is that MinGW uses the Microsoft C run-time libraries which do not have good support for the long double type. Attempts to print it will result in weird behaviour. As a workaround, a long double may be cast to double before being printed.