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

不羁岁月 提交于 2019-12-17 18:28:29

问题


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!


回答1:


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




回答2:


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.




回答3:


When there is a literal value it is considered to be of a certain type. 3.0 is considered a double 3 is considered an int. 3.0F makes it in to a float instead of a double 3.0L makes it a long double instead of a double. 3L is a long int instead of an int.

Note at least in g++, and VS08 both of your examples work just fine.




回答4:


Your example does not need it, but the biggest reason I know of to use explicit types on literal values is to make sure that the correct function overload is called.

This can make a large difference in constructors, operator overloads, etc.

Sometimes there is no convenient way to get the literal into the right type, so you have to use a static_cast or put a constructor around the literal.



来源:https://stackoverflow.com/questions/1380653/why-do-you-need-to-append-an-l-or-f-after-a-value-assigned-to-a-c-constant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!