# Difference between revisions of "Long double"

(Created page with "{{DISPLAYTITLE:long double}} <code>long double</code> is a primitive floating-point data type in C (and subsequently C++) that is required by the standard to be at least as long ...") |
(Added useful info) |
||

Line 3: | Line 3: | ||

On many architectures, <code>long double</code> is identical to <code>double</code>, since <code>double</code> is usually a [[IEEE 754|binary64]] and many architectures do not support a longer floating-point data type. On Intel x86 machines, however, <code>long double</code> 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. | On many architectures, <code>long double</code> is identical to <code>double</code>, since <code>double</code> is usually a [[IEEE 754|binary64]] and many architectures do not support a longer floating-point data type. On Intel x86 machines, however, <code>long double</code> 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 <code>Extended</code> (Free/Borland/GNU Pascal) and also <code>LongReal</code> (GNU Pascal), which also hold 80 bits of information. | ||

+ | |||

+ | ==Properties== | ||

+ | The range of a <code>long double</code> can be checked in C using <code><float.h></code> and C++ using <code>std::numeric_limits</code>. 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 <code>long double</code> may be stored using 96 or even 128 bits (you can check the number of bits using <code>4*sizeof(long double)</code>), 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 <code>-m96bit-long-double</code> and <code>-m128bit-long-double</code> may be used to control the storage size of a <code>long double</code>, without of course, changing its precision in any way. | ||

+ | |||

+ | ==Usage== | ||

+ | To <code>scanf</code> or <code>printf</code> a <code>long double</code>, one should use the format specifier <code>%Lf</code> (<code>%llf</code> 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 <code>long double</code> type. Attempts to print it will result in weird behaviour. As a workaround, a <code>long double</code> may be cast to <code>double</code> before being printed. |

## Revision as of 22:22, 20 August 2014

`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 `4*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.