What is the precision of long double in C++?
You can find out with std::numeric_limits
:
#include <iostream> // std::cout
#include <limits> // std::numeric_limits
int main(){
std::cout << std::numeric_limits<long double>::digits10 << std::endl;
}
sizeof long double and precision not matching?
The long double
format in your C implementation uses an Intel format with a one-bit sign, a 15-bit exponent, and a 64-bit significand (ten bytes total). The compiler allocates 16 bytes for it, which is wasteful but useful for some things such as alignment. However, the 64 bits provide only log10(264) digits of significance, which is about 20 digits.
How to identify the precision of long double datatype
I want to know until how many digits the precision can handle.
LDBL_DIG
, in <float.h>
, is the number of minimum number of significant decimal digits that will be converted from text to long double
distinctively. It is at least 10 and may be 18 or so on your platform. 0.1234567812345678
and 123.4567812345678
have 16 significant decimal digits.
My compiler is telling me that the size of sizeof(long double) is 16 byte, which means it can represent a number up 2^128
It could mean something like that if long double
was an integer, yet floating point numbers are distributed logarithmically. Further, some systems do not use all 16 bytes for data. Some are padding. @unwind @Sven Marnach. Use the values in <float.h>
to characterize the long double
your platform is using.
if
x= 0.1234567812345678
, canlong double
identify the exact precision ofx
?
No, unless you are on a rare platform that uses decimal floating point.
Most platforms use a binary floating point. So unless the number can be represented as an exact sum of powers of 2, like 42.125, the value saved as a long double
will be a nearby approximation. Code will convert text 0.1234567812345678
to the nearest long double
which may have an exact value of 0.1234567812345677972896140772718354128301143646240234375
.
Long Double vs Long Long
long long
is integer (possibly with more range than long
)long double
is floating point (possibly with more range/precision than double
)long float
does not exist.
The integer types sorted by range are
_Bool
char
orsigned char
orunsigned char
short
(orshort int
) orshort unsigned
int
orunsigned
long
(orlong int
) orlong unsigned
long long
(orlong long int
) orlong long unsigned
The floating-point types sorted by range/precision are
float
double
long double
Difference between long double and double in C and C++
To quote the C++ standard, §3.9.1 ¶8:
There are three floating point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. Integral and floating types are collectively called arithmetic types. Specializations of the standard template std::numeric_limits (18.3) shall specify the maximum and minimum values of each arithmetic type for an implementation.
That is to say that double
takes at least as much memory for its representation as float
and long double
at least as much as double
. That extra memory is used for more precise representation of a number.
On x86 systems, float
is typically 4 bytes long and can store numbers as large as about 3×10³⁸ and about as small as 1.4×10⁻⁴⁵. It is an IEEE 754 single-precision number that stores about 7 decimal digits of a fractional number.
Also on x86 systems, double
is 8 bytes long and can store numbers in the IEEE 754 double-precision format, which has a much larger range and stores numbers with more precision, about 15 decimal digits. On some other platforms, double
may not be 8 bytes long and may indeed be the same as a single-precision float
.
The standard only requires that long double
is at least as precise as double
, so some compilers will simply treat long double
as if it is the same as double
. But, on most x86 chips, the 10-byte extended precision format 80-bit number is available through the CPU's floating-point unit, which provides even more precision than 64-bit double
, with about 21 decimal digits of precision.
Some compilers instead support a 16-byte (128-bit) IEEE 754 quadruple precision number format with yet more precise representations and a larger range.
Long double precision error saturation in RK integrator
but for some reason, the precision of my integrator maxes out at 16 significant digits.
At a minimum, use more correct values of long double
initialization with long double
quotients rather than double
quotients.
// long double a2 = 2.0 / 7.0;
long double a2 = 2.0L / 7.0L;
Like-wise for the other 19 initializations.
Related Topics
Why Are Strings in C++ Usually Terminated with '\0'
Why Do We Need to Use Boost::Asio::Io_Service::Work
How to Use Std::Sort with a Vector of Structures and Compare Function
Does Delete on a Pointer to a Subclass Call the Base Class Destructor
How Does the Range-Based for Work for Plain Arrays
C++ Correct Way to Return Pointer to Array from Function
Difference Between <String> and <String.H>
How to Escape a String for Use in Boost Regex
Constexpr Static Member Before/After C++17
Copy Constructor of Template Class
How to Access a Local Variable in Outer Scope in C++
What Are the Issues with a Vector-Of-Vectors
Write Applications in C or C++ for Android
Is There a Linq Library for C++