Floating-point constants have type double
by default in C++. Since a long double
is more precise than a double
, you may lose significant digits when long double
constants are converted to double
. To handle these constants, you need to use the L
suffix to maintain long double
precision. For example,
long double x = 8.99999999999999999;
long double y = 8.99999999999999999L;
std::cout.precision(100);
std::cout << "x=" << x << "\n";
std::cout << "y=" << y << "\n";
The output for this code on my system, where double
is 64 bits and long double
96, is
x=9
y=8.9999999999999999895916591441391574335284531116485595703125
What's happening here is that x
gets rounded before the assignment, because the constant is implicitly converted to a double
, and 8.99999999999999999
is not representable as a 64-bit floating point number. (Note that the representation as a long double
is not fully precise either. All of the digits after the first string of 9
s are an attempt to approximate the decimal number 8.99999999999999999
as closely as possible using 96 binary bits.)
In your example, there is no need for the L
constant, because 3.0
is representable precisely as either a double
or a long double
. The double
constant value is implicitly converted to a long double
without any loss of precision.
The case with F
is not so obvious. It can help with overloading, as Zan Lynx points out. I'm not sure, but it may also avoid some subtle rounding errors (i.e., it's possible that encoding as a float
will give a different result from encoding as a double
then rounding to a float
).