Why would you add L or F after the value assigned to the C ++ constant?

I have looked at quite a few places on the Internet and cannot find the right explanation why we should add F or L after the value assigned to the C ++ constant. For example:

const long double MYCONSTANT = 3.0000000L; 

Can someone explain why this is necessary? Doesn't a type declaration mean that the value assigned by MYCONSTANT is long double? What is the difference between the above line and

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

Phew!

+10
c ++ syntax types constants
Sep 04 '09 at 17:47
source share
4 answers

Floating point constants are of type double by default in C ++. Since a long double more accurate than a double , you can lose significant digits when the constants of long double 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 is on my system, where double is 64 bits and long double 96, is

 x=9 y=8.9999999999999999895916591441391574335284531116485595703125 

What happens is that x rounded to the destination, because the constant is implicitly converted to double , and 8.99999999999999999 not represented as a 64-bit floating point number. (Note that the representation as a long double also not completely accurate. All digits after the first line of 9 are attempts to approximate the decimal number 8.99999999999999999 as close as possible using 96 binary bits.)

In your example, there is no need for the constant L , since 3.0 is represented exactly as either double or long double . The value of the double constant is implicitly converted to long double without loss of precision.

The case with F not so obvious. This can help with overload, as Zan Links points out. I'm not sure, but it can also avoid some subtle rounding errors (i.e., it is possible that encoding as float will give a different result from encoding as double , and then rounding to float ).

+12
Sep 04 '09 at 23:13
source share

No, declaration does not mean that the initializer has a certain type. The initialization type is the same no matter what type the variable initializes.

So, if you initialize a long double , but use double for intialization, that would be pretty stupid. Using the suffix L , you say this is a floating point literal of type long double . Added to the integer literal, he would say that the type has a long int .

+13
Sep 04 '09 at 17:50
source share

When there is a literal meaning, it is considered a certain type. 3.0 is considered double 3 is considered int. 3.0F turns it into a float instead of a double 3.0L, which makes it a long double, not a double. 3L is a long int instead of int.

Note that at least in g ++ and VS08 both of your examples work very well.

+4
Sep 04 '09 at 17:54
source share

He does not need your example, but the biggest reason I know to use explicit types for literal values ​​is to cause the function to overload correctly.

This can significantly affect constructors, operator overloads, etc.

Sometimes there is no convenient way to get a literal in the desired type, so you need to use static_cast or place the constructor around the literal.

+1
Sep 05 '09 at 4:59
source share



All Articles