Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do you need to append an L or F after a value assigned to a C++ constant?

I have looked at quite a few places online and can't seem to find a good explanation as to why we should append an F or L after a value assigned to a C++ constant. For example:

const long double MYCONSTANT = 3.0000000L;

Can anyone explain why that is necessary? Doesn't the type declaration imply the value assigned to MYCONSTANT is a long double? What is the difference between the above line and

const long double MYCONSTANT = 3.0000000;        // no 'L' appended

Whew!

like image 775
ybakos Avatar asked Sep 04 '09 17:09

ybakos


People also ask

What is the purpose of appending the letter F and the end of a float type of data in Java?

The "F" indicates that the literal numeric value it is appended to is a float value. This is necessary information for the compiler and if not present can lead to errors or the compiler otherwise interpreting the number incorrectly.

What does F mean after a number in C?

f means float. It's like a C programming language.

What is L in C programming?

The C Programming Language says: An integer constant like 1234 is an int . A long constant is written with a terminal l (ell) or L , as in 123456789L ; an integer constant too big to fit into an int will also be taken as a long .


2 Answers

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 9s 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).

like image 65
Chris Conway Avatar answered Oct 05 '22 18:10

Chris Conway


No, the declaration does not imply that the initializer has a specific type. The type of the initialize is the same, no matter what type the variable initialized is.

So, if you initialize a long double, but use a double for intialization, that would be pretty silly. By using the L suffix, you say it's a floating point literal of type long double. Appended to an integer literal, it would say the type has long int.

like image 32
Johannes Schaub - litb Avatar answered Oct 05 '22 17:10

Johannes Schaub - litb