It is not an error to declare float a = 3.0 : if you do, the compiler will convert the double literal 3.0 to a float for you.
However, you should use the float literals notation in specific scenarios.
-
For performance reasons:
Specifically, consider:
float foo(float x) { return x * 0.42; }Here the compiler will emit a conversion (that you will pay at runtime) for each returned value. To avoid it you should declare:
float foo(float x) { return x * 0.42f; } // OK, no conversion required -
To avoid bugs when comparing results:
e.g. the following comparison fails :
float x = 4.2; if (x == 4.2) std::cout << "oops"; // Not executed!We can fix it with the float literal notation :
if (x == 4.2f) std::cout << "ok !"; // Executed!(Note: of course, this is not how you should compare float or double numbers for equality in general)
-
To call the correct overloaded function (for the same reason):
Example:
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } int main() { foo(42.0); // calls double overload foo(42.0f); // calls float overload return 0; } -
As noted by Cyber, in a type deduction context, it is necessary to help the compiler deduce a
float:In case of
auto:auto d = 3; // int auto e = 3.0; // double auto f = 3.0f; // floatAnd similarly, in case of template type deduction :
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } template<typename T> void bar(T t) { foo(t); } int main() { bar(42.0); // Deduce double bar(42.0f); // Deduce float return 0; }
Live demo