What's the C++ Suffix for Long Double Literals

What's the C++ suffix for long double literals?

From the C++ Standard

The type of a floating literal is double unless explicitly specified
by a suffix. The suffixes f and F specify float, the suffixes l and L
specify long double.

It is interesting to compare with corresponding paragraph of the C Standard. In C there is used term floating constant instead of floating literal in C++:

4 An unsuffixed floating constant has type double. If suffixed by the letter f or F, it has type float. If suffixed by the letter l or L, it has type long double

How can the suffix for numeric literals long int and long double both be l/L?

A literal number needs to have a period or an exponent to be treated as a floating point literal constant. If it doesn't have any of these, it is treated as an integer literal constant.

C++ suffix L vs specifying long double

I am confused why not to specify long int i = 33 instead of int i = 33L?

Because that 2 statements mean 2 different things:

long int i = 33; // take constant of type int, convert it to long int and assign to i.

int i = 33L; // take constant of type long int, convert it to int and assign to i.

So you end up with variable i of different type. Same for the double in your example.

Appending long double literal suffix to user inputs in c++

Use std::stold to convert input text to long double. There is no need for a suffix; stold will do it right. The suffix is needed in source code to tell the compiler what type the text represents. When you're reading from an external source the compiler isn't involved, so you have to sort out the type yourself.

Is there any difference between using floating point casts vs floating point suffixes in C and C++?

The default is double. Assuming IEEE754 floating point, double is a strict superset of float, and thus you will never lose precision by not specifying f. EDIT: this is only true when specifying values that can be represented by float. If rounding occurs this might not be strictly true due to having rounding twice, see Eric Postpischil's answer. So you should also use the f suffix for floats.


This example is also problematic:

long double MY_LONG_DOUBLE = (long double)3.14159265358979323846264338328;

This first gives a double constant which is then converted to long double. But because you started with a double you have already lost precision that will never come back. Therefore, if you want to use full precision in long double constants you must use the L suffix:

long double MY_LONG_DOUBLE = 3.14159265358979323846264338328L; // L suffix

The type of a floating point literal with exponent

By default, all floating point literals, with or without an exponent part, have type double. You can add the f suffix to make the type float or L to make the type long double.

In the case of float f = 123456e-3;, you're initializing a float with a double constant, so there is the possibility of loss of precision, however this particular constant only has 6 decimal digits of precision so it should be OK.

Is there any C++ style guide that talks about numeric literal suffixes?

There is no general style guide that I've found. I use capital letters and I'm picky about using F for float literals and L for long double. I also use the appropriate suffixes for integral literals.

I assume you know what these suffixes mean: 3.14F is a float literal, 12.345 is a double literal, 6.6666L is a long double literal.

For integers: U is unsigned, L is long, LL is long long. Order between U and the Ls doesn't matter but I always put UL because I declare such variables unsigned long for example.

If you assign a variable of one type a literal of another type, or supply a numeric literal of one type for function argument of another type a cast must happen. Using the proper suffix avoids this and is useful along the same lines as static_cast is useful for calling out casts. Consistent usage of numeric literal suffixes is good style and avoids numeric surprises.

People differ on whether lower or upper case is best. Pick a style that looks good to you and be consistent.

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

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



Related Topics



Leave a reply



Submit