... 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 << "
max " << lim_d.max() << " " << lim_ld.max()
<< "
min " << lim_d.min() << " " << lim_ld.min()
<< "
lowest " << lim_d.lowest() << " " << lim_ld.lowest()
<< "
digits10 " << lim_d.digits10 << " " << lim_ld.digits10
<< '
';
}
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
.