为什么需要在分配给 C++ 的值后附加 L 或 F持续的?
我在网上浏览了很多地方,似乎找不到一个很好的解释来解释为什么我们应该在分配给 C++ 常量的值后面附加 F 或 L。例如:
const long double MYCONSTANT = 3.0000000L;
谁能解释为什么这是必要的?类型声明是否暗示分配给 MYCONSTANT 的值是一个 long double ?上面的行和
const long double MYCONSTANT = 3.0000000; // no 'L' appended
唷!
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在 C++ 中,浮点常量默认为 double 类型。由于
long double
比double
更精确,因此当long double
常量转换为double
时,您可能会丢失有效数字。代码>.要处理这些常量,您需要使用L
后缀来保持long double
精度。例如,此代码在我的系统上的输出,其中
double
是 64 位,long double
96,这里发生的是
x
在赋值之前进行舍入,因为常量被隐式转换为 double,并且 8.99999999999999999 不能表示为 64 位浮点数。 (请注意,long double
的表示也不完全精确。第一个9
字符串后面的所有数字都是对十进制数的近似值>8.99999999999999999
尽可能使用 96 个二进制位。)在您的示例中,不需要
L
常量,因为3.0
可以精确地表示为double
或long double
。double
常量值会隐式转换为long double
,而不会损失任何精度。F
的情况并不那么明显。正如 Zan Lynx 指出的那样,它可以帮助缓解超载。我不确定,但它也可能避免一些微妙的舍入错误(即,编码为float
可能会得到与编码为double
不同的结果,然后四舍五入为浮点数
)。Floating-point constants have type
double
by default in C++. Since along double
is more precise than adouble
, you may lose significant digits whenlong double
constants are converted todouble
. To handle these constants, you need to use theL
suffix to maintainlong double
precision. For example,The output for this code on my system, where
double
is 64 bits andlong double
96, isWhat's happening here is that
x
gets rounded before the assignment, because the constant is implicitly converted to adouble
, and8.99999999999999999
is not representable as a 64-bit floating point number. (Note that the representation as along double
is not fully precise either. All of the digits after the first string of9
s are an attempt to approximate the decimal number8.99999999999999999
as closely as possible using 96 binary bits.)In your example, there is no need for the
L
constant, because3.0
is representable precisely as either adouble
or along double
. Thedouble
constant value is implicitly converted to along 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 afloat
will give a different result from encoding as adouble
then rounding to afloat
).不,声明并不意味着初始化器具有特定类型。无论初始化的变量是什么类型,初始化的类型都是相同的。
因此,如果您初始化一个
long double
,但使用double
进行初始化,那将是非常愚蠢的。通过使用L
后缀,您可以说它是long double
类型的浮点文字。附加到整数文字后,它会表示该类型具有long int
。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 adouble
for intialization, that would be pretty silly. By using theL
suffix, you say it's a floating point literal of typelong double
. Appended to an integer literal, it would say the type haslong int
.当存在文字值时,它被认为是某种类型。 3.0 被视为双精度型 3 被视为整数型。 3.0F 使其成为浮点数而不是双精度数 3.0L 使其成为长双精度数而不是双精度数。 3L 是一个 long int 而不是 int。
请注意,至少在 g++ 和 VS08 中,您的两个示例都工作得很好。
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.
您的示例不需要它,但我知道对文字值使用显式类型的最大原因是确保调用正确的函数重载。
这可能会在构造函数、运算符重载等方面产生很大的差异。
有时没有方便的方法将文字转换为正确的类型,因此您必须使用 static_cast 或在文字周围放置构造函数。
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.