Is there a functional difference between "2.00" and "2.00f"?
I ask because I am using the Box2D library, which calls for mostly float arguments. Although I see a lot of 开发者_运维知识库example code that uses the 0.00f format, I am not quite sure if there is an actual difference between that and plain old 0.00.
Will I be hurting myself later on by not appending the additional f? Is it a speed thing? Is there some sort of connotation that would need the f addend when others wouldn't?
TL;DR: Why should I be using 0.00f instead of 0.00?
The f
suffix makes it a single precision(float) literal instead of a double precision literal. This usually means 32 bit instead of 64 bit floats.
Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.
http://msdn.microsoft.com/en-us/library/tfh6f0w2(v=VS.100).aspx
There is a difference. 2.00
has type double
and 2.00f
has type float
. The exact precision and format implications of this depends on your platform. Whether the use of one over the other makes a practical difference in your code depends on the context in which it is used.
As an initializer for an explicity typed variable (of a fundamental numeric type), there will be no difference but when used in a function call it might potentially affect which overload or template specialization is used.
Obviously, when used as an initializer in a declaration using the auto
type-specifier or as an expression in a decltype-specifier, the type of the object being declared will be affected.
decltype(2.00) x = 2.00f; // confusing
decltype(2.00f) y = 2.00; // also confusing
auto d = 2.00;
auto f = 2.00f;
As long as you assign them to a float
, there's absolutely no difference, since the value is representable precisely and correctly in all numeric types.
The important difference is the type of the literal, which is double
for 2.0
, float
for 2.0f
and int
for 2
. So it makes a difference in argument type deduction:
void foo(int) { cure_cancer(); };
void foo(float) { wipe_hard_disk(); }
void foo(double) { exit(0); }
foo(2);
foo(2.0f);
foo(2.0);
The default assumption is double
. specifying f
suffix ensures that it will be interpreted as a float
The type of 2.00
is double
, and the type of 2.00f
is float
.
The suffix f
turns the literal 2.00
into a float type, decreasing its precision. Otherwise, literal is double
type.
The suffix affects the type, which changes how a statement is parsed
This not only changes type deduction result via
decltype
and function overload selection as others said, but also how an expression is evaluatedFor example
2.0 * x / 3
is done in double precision, and2.0f * x / 3
is done in float precision when x isfloat
. That may lead to different results because doing in a higher precision will reduce any intermediate errors. It also affects performance greatly on FPU-less systems or systems with an FPU forfloat
only, and it's a thing embedded programmers need to care about. Demo on GodboltHere I'm assuming the
FLT_EVAL_METHOD
macro is set so that floating-point types are not evaluated in a higher precision. But even ifFLT_EVAL_METHOD >= 1
then the result might still be different with and without the suffix, because of the next point:The suffix also affects the value
In C++ the value must be rounded correctly to the nearest value in the destination type. So for example when we have
float f1 = 8388608.5000000009f; float f2 = 8388608.5000000009;
then
f1
andf2
will have different values because the suffix prevents double rounding (meaning rounding twice, not the typedouble
) from happening inf2
(decimal → double → float). The decimal value is rounded to the nearestfloat
value directly inf1
(decimal → float) without going throughdouble
. Print the values with more precision and you'll seeAnother example:
f1 = 7.038531e-26f; f2 = 7.038531e-26;
There are many other examples that you can see in the demo
See also
- When does appending an 'f' change the value of a floating constant when assigned to a `float`?
- The type of a floating point literal with exponent
- Notation of double floating point values in C and C++
- What's the use of suffix
f
on float value - Is there any difference between using floating point casts vs floating point suffixes in C and C++?
- What is the difference between casting to `float` and adding `f` as a suffix when initializing a `float`?
- "i < 0.7" is true following an "float i = 0.7" initialization above?
精彩评论