Long Double VS 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 vs double

Quoting from Wikipedia:

On the x86 architecture, most compilers implement long double as the 80-bit extended precision type supported by that hardware (sometimes stored as 12 or 16 bytes to maintain data structure .

and

Compilers may also use long double for a 128-bit quadruple precision format, which is currently implemented in software.

In other words, yes, a long double may be able to store a larger range of values than a double. But it's completely up to the compiler.

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 or signed char or unsigned char
  • short (or short int) or short unsigned
  • int or unsigned
  • long (or long int) or long unsigned
  • long long (or long long int) or long long unsigned

The floating-point types sorted by range/precision are

  • float
  • double
  • long double

What is the difference between double and long double data type in c language

What is the major difference between double and long double data type in c?

Quoting from N1570 section "6.2.5 Types" this is what the C standard says:

There are three real floating types, designated as float, double, and long
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

This means that long double is a floating point type having at least the same precision as the floating point type double.

So maybe long double is the same as double. Maybe it has better precision than double. The C standard only tells us that long double can't have worse precision than double.

This is further expanded in Annex E of the standard where the "minimum requirements" for double and long double is the same.

So the difference - if any - depends on your system.

Also notice that <float.h> on your system gives you information about the three floating point types on your system. For that please refer to the "5.2.4.2.2 Characteristics of floating types <float.h>" of the standard - it's too much info to be pasted into this answer.

BTW:

Instead of using pointer values you could have printed the size, like:

printf("size of double %zu\n", sizeof(double));
printf("size of long double %zu\n", sizeof(long double));

If the sizes are different then it is very likely that long double has better precision than double.

I want to know the difference between a long double and a double

... long double is known to be more accurate than double.

No, it's really not. It may be but it's by no means guaranteed.

The difference between the two types is detailed in the standard (in this case, C++17 [basic.fundamental]/8, though earlier iterations also have similar wording). The standard has this to say about the floating point types (my emphasis):

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.

Since "subset" includes the possibility that the two sets are identical (it's axiomatic that A ⊂ A), there's no actual requirement than long double has a larger range and/or precision than double, though it sometimes does.

If you want to figure out what the differences are in your implementation, you should be looking into the numeric_limits class in the <limits> header, as per the following demo program:

#include <iostream>
#include <limits>
using namespace std;

int main() {
numeric_limits<double> lim_d;
numeric_limits<long double> lim_ld;

cout << "\nmax " << lim_d.max() << " " << lim_ld.max()
<< "\nmin " << lim_d.min() << " " << lim_ld.min()
<< "\nlowest " << lim_d.lowest() << " " << lim_ld.lowest()
<< "\ndigits10 " << lim_d.digits10 << " " << lim_ld.digits10
<< '\n';
}

The output on my system is, formatted for readability:

              double        long double
============ =============
max 1.79769e+308 1.18973e+4932
min 2.22507e-308 3.3621 e-4932
lowest -1.79769e+308 -1.18973e+4932
digits10 15 18

You can see that my range is substantially larger for a long double and there's also (roughly) an extra three decimal digits of precision.


In terms of what effect this can have on your code, it's difficult to say since you haven't actually provided an adequate description of what the problem is (specifically what wa and ac mean). However, since a long double may have more precision and/or range than a double, it's certainly conceivable that this may affect how your code behaves.

I should also mention that the correct format specifier for a long double is actually %Lf (capitalised L) rather than %lf. That may well be causing a problem for you since, with the test data given on the page you linked to in a comment, I get the correct result for double/%f and long double/%Lf.

But it gives different results (and a gcc warning, for that matter) for long double/%lf.

Does double have a greater range than long?

The number of possible doubles, and the number of possible longs is the same, they are just distributed differently*.

The longs are uniformly distributed, while the floats are not. You can Read more here.

I'd write more, but for some reason the cursor is jumping around all over the place on my phone.

Edit: This might actually be more helpful: http://en.wikipedia.org/wiki/Double-precision_floating-point_format#section_1

Edit2: and this is even better: http://blogs.msdn.com/b/dwayneneed/archive/2010/05/07/fun-with-floating-point.aspx

* According to that link, it would seem that there are actually more longs, since some doubles are lost due to the way NaNs and other special numbers are represented.

what is the exact range of long double in c++?

Why not ask your compiler? std::numeric_limits<long double> is defined.

long double smallest = std::numeric_limits<long double>::min();
long double largest = std::numeric_limits<long double>::max();
long double lowest = std::numeric_limits<long double>::lowest();
std::cout << "lowest " << lowest << std::endl;
std::cout << "largest " << largest << std::endl;
std::cout << "smallest " << smallest << std::endl;

Running this code on godbolt.org with x86-64 GCC 11.2 gives me:

lowest -1.18973e+4932
largest 1.18973e+4932
smallest 3.3621e-4932

It might vary for your platform, of course.



Related Topics



Leave a reply



Submit